package ext.tianma.bom.util;

import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.log4j.Logger;

import wt.access.AccessControlHelper;
import wt.access.AccessPermission;
import wt.change2.ChangeHelper2;
import wt.change2.WTChangeActivity2;
import wt.change2.WTChangeOrder2;
import wt.clients.vc.VersionTaskLogic;
import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.content.ContentItem;
import wt.content.ContentRoleType;
import wt.content.ContentServerHelper;
import wt.content.FormatContentHolder;
import wt.content.StandardContentService;
import wt.doc.DepartmentList;
import wt.doc.DocumentMaster;
import wt.doc.DocumentType;
import wt.doc.WTDocument;
import wt.doc.WTDocumentDependencyLink;
import wt.doc.WTDocumentHelper;
import wt.doc.WTDocumentMaster;
import wt.doc.WTDocumentMasterIdentity;
import wt.enterprise.Master;
import wt.epm.EPMApplicationType;
import wt.epm.EPMAuthoringAppType;
import wt.epm.EPMAuthoringAppVersion;
import wt.epm.EPMContextHelper;
import wt.epm.EPMDocConfigSpec;
import wt.epm.EPMDocSubType;
import wt.epm.EPMDocument;
import wt.epm.EPMDocumentMaster;
import wt.epm.EPMDocumentMasterIdentity;
import wt.epm.EPMDocumentType;
import wt.epm.structure.EPMDescribeLink;
import wt.epm.structure.EPMMemberLink;
import wt.epm.structure.EPMReferenceLink;
import wt.epm.structure.EPMReferenceType;
import wt.epm.structure.EPMStructureHelper;
import wt.epm.workspaces.EPMPopulateRule;
import wt.epm.workspaces.EPMWorkspace;
import wt.fc.EnumeratedType;
import wt.fc.Identified;
import wt.fc.IdentityHelper;
import wt.fc.ObjectIdentifier;
import wt.fc.ObjectNoLongerExistsException;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.fc.WTReference;
import wt.filter.NavigationCriteria;
import wt.folder.Folder;
import wt.folder.FolderEntry;
import wt.folder.FolderHelper;
import wt.folder.FolderNotFoundException;
import wt.folder.SubFolder;
import wt.httpgw.GatewayServletHelper;
import wt.httpgw.GatewayURL;
import wt.httpgw.URLFactory;
import wt.iba.definition.StringDefinition;
import wt.iba.value.StringValue;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerRef;
import wt.inf.library.WTLibrary;
import wt.inf.team.ContainerTeamHelper;
import wt.inf.team.ContainerTeamManaged;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.LifeCycleTemplate;
import wt.lifecycle.LifeCycleTemplateReference;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.method.MethodContext;
import wt.method.RemoteAccess;
import wt.occurrence.OccurrenceHelper;
import wt.org.WTGroup;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.part.LineNumber;
import wt.part.PartUsesOccurrence;
import wt.part.Quantity;
import wt.part.QuantityUnit;
import wt.part.WTPart;
import wt.part.WTPartConfigSpec;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartMasterIdentity;
import wt.part.WTPartStandardConfigSpec;
import wt.part.WTPartUsageLink;
import wt.pdmlink.PDMLinkProduct;
import wt.pom.PersistentObjectManager;
import wt.pom.Transaction;
import wt.project.Role;
import wt.query.ClassAttribute;
import wt.query.ExistsExpression;
import wt.query.KeywordExpression;
import wt.query.OrderBy;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.recent.RecentlyVisitedHelper;
import wt.representation.PublishedContentLink;
import wt.session.SessionHelper;
import wt.session.SessionMgr;
import wt.session.SessionServerHelper;
import wt.team.Team;
import wt.type.TypeDefinitionReference;
import wt.type.TypedUtility;
import wt.type.TypedUtilityServiceHelper;
import wt.util.WTAttributeNameIfc;
import wt.util.WTContext;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.util.WTPropertyVetoException;
import wt.util.WTRuntimeException;
import wt.vc.Iterated;
import wt.vc.Mastered;
import wt.vc.OneOffVersionIdentifier;
import wt.vc.OneOffVersionInfo;
import wt.vc.VersionControlHelper;
import wt.vc.Versioned;
import wt.vc.baseline.Baseline;
import wt.vc.baseline.BaselineHelper;
import wt.vc.baseline.ManagedBaseline;
import wt.vc.config.BaselineConfigSpec;
import wt.vc.config.ConfigHelper;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.config.LifeCycleConfigSpec;
import wt.vc.views.View;
import wt.vc.views.ViewHelper;
import wt.vc.wip.CheckoutLink;
import wt.vc.wip.WorkInProgressHelper;
import wt.vc.wip.Workable;
import wt.workflow.engine.WfProcess;

import com.ptc.core.lwc.common.view.AttributeDefinitionReadView;
import com.ptc.core.lwc.common.view.ConstraintDefinitionReadView;
import com.ptc.core.lwc.common.view.ConstraintDefinitionReadView.RuleDataObject;
import com.ptc.core.lwc.common.view.EnumerationEntryReadView;
import com.ptc.core.lwc.common.view.TypeDefinitionReadView;
import com.ptc.core.lwc.server.TypeDefinitionServiceHelper;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.core.meta.type.mgmt.server.impl.WTTypeDefinition;
import com.ptc.windchill.cadx.common.preference.EpdParams;
import com.ptc.windchill.cadx.common.util.WorkspaceConfigSpecUtilities;
import com.ptc.windchill.cadx.common.util.WorkspaceUtilities;

public class GenericUtil implements RemoteAccess {

	private static final Logger log = LogR.getLogger(GenericUtil.class.getName());

	public static String DEFAULT_CHARSET = "UTF-8";

	public static ReferenceFactory REF_FACTORY = new ReferenceFactory();
	public static Locale LOCALE = null;
	// String oid = GenericUtil.REF_FACTORY.getReferenceString(obj);
	// Object obj = GenericUtil.REF_FACTORY.getReference(oid).getObject();
	public static String CONTAINER_ROOT_FOLDER = "/Default";

	public static String ROLE_LIBRARY_MANAGER = "LIBRARY MANAGER";

	public static String CADDOCTYPE_PUB_GRAPHIC = "PUB_GRAPHIC";

	public static String CODEBASE_LOCATION = null;

	public static List BOOK_SUBFOLDERS = null;

	public static String HOSTNAME = null;

	public static URLFactory URL_FACTORY = null;

	public static String CODEBASE_WEBAPP = null;

	static {
		try {
			WTDocument doc = null;

			WTProperties wtproperties = WTProperties.getLocalProperties();
			LOCALE = WTContext.getContext().getLocale();
			HOSTNAME = wtproperties.getProperty("java.rmi.server.hostname");
			CODEBASE_LOCATION = wtproperties.getProperty("wt.codebase.location");
			// String templateFolderName =
			// wtproperties.getProperty("ext.generic.folder.templateFolderName");
			// BOOK_SUBFOLDERS = getOptions(templateFolderName);
			CODEBASE_WEBAPP = wtproperties.getProperty("wt.webapp.name",
			"Windchill");

			URL_FACTORY = new URLFactory();
		} catch (Exception ex) {
			//log.debug("Error: GenericUtil initializing error!");
			ex.printStackTrace();
		}
	}

	public static String getOid(Persistable p) throws Exception {
		return REF_FACTORY.getReferenceString(p);
	}
	
	public static String getFileUrl(String filename) throws Exception {
	    String url = null;
	    if(filename==null)
	      return null;
	    if(filename.startsWith(CODEBASE_LOCATION)){
	      url = filename.substring(CODEBASE_LOCATION.length());
	      url = "/Windchill"+url.replace('\\', '/');
	    }
	    return url;
	  }

	/**
	 * create ReferenceLink between EPM Doc and WTDoc
	 *
	 * @param doc1
	 * @param doc2
	 * @throws Exception
	 */
	// public static void createEPMReferenceLink(EPMDocument doc1, WTDocument
	// doc2)
	// throws Exception {
	// if (doc1 == null || doc2 == null)
	// return;
	// EPMReferenceLink link = EPMReferenceLink.newEPMReferenceLink(doc1,
	// doc2);
	// link.setReferenceType(EPMReferenceType.toEPMReferenceType("INTERNAL"));
	// PersistenceServerHelper.manager.insert(link);
	// }
	/**
	 * check any Reference between EPMDoc and WTDoc
	 *
	 * @param epmdoc
	 * @param wtdoc
	 * @return
	 * @throws Exception
	 */
	public static boolean isReference(EPMDocument epmdoc, WTDocument wtdoc) throws Exception {
		if (epmdoc == null || wtdoc == null) {
			return false;
		}
		wt.fc.QueryResult qr = wt.epm.structure.EPMStructureHelper.service.navigateReferences(epmdoc, null, true);
		while (qr.hasMoreElements()) {
			Object obj = qr.nextElement();
			if (obj instanceof WTDocumentMaster) {
				WTDocumentMaster doc = (WTDocumentMaster) obj;
				if (wtdoc.getNumber().equals(doc.getNumber())) {
					return true;
				}
			}

		}
		return false;
	}

	/**
	 * get LangZip state by BookMap
	 *
	 * @param epmdoc
	 *            BookMap
	 * @param language_code
	 *            language code
	 * @return
	 * @throws Exception
	 */
	public static String getReferenceLangZipStatus(EPMDocument epmdoc, String language_code) throws Exception {
		String rt = null;
		if (epmdoc == null) {
			return null;
		}
		String langDocNumber = epmdoc.getNumber() + "_" + language_code;
		//log.debug("begin Find Lang Doc For Lang:" + language_code + " MapDoc:" + epmdoc);

		wt.fc.QueryResult qr = wt.epm.structure.EPMStructureHelper.service.navigateReferences(epmdoc, null, true);
		while (qr.hasMoreElements()) {
			Object obj = qr.nextElement();
			if (obj instanceof WTDocumentMaster) {
				WTDocumentMaster doc = (WTDocumentMaster) obj;
				if (doc.getNumber().equalsIgnoreCase(langDocNumber)) {
					//log.debug("Find Lang Doc For Lang:" + language_code + " Doc:" + doc);
					rt = GenericUtil.getWTDocument(doc.getNumber()).getLifeCycleState().getDisplay();
					break;
				}
			}
		}
		return rt;
	}

	/**
	 * get Options from a string
	 *
	 * @param confFile
	 * @return
	 * @throws Exception
	 */
	public static List getOptions(String confFile) throws Exception {
		List options = new ArrayList();
		BufferedReader in = new BufferedReader(new FileReader(confFile));
		while (true) {
			String line = in.readLine();
			if (line == null)
				break;
			if (line.startsWith("#"))
				continue;
			options.add(line);
		}
		return options;
	}

	/**
	 * create a Folder
	 *
	 * @param name
	 *            folder Name
	 * @param softType
	 *            folder type
	 * @param parentFolder
	 *            parent Folder
	 * @param iba
	 *            folder IBA value
	 * @return
	 * @throws Exception
	 */
	public static SubFolder createSubFolder(String name, String softType, Folder parentFolder, Map iba) throws Exception {
		SubFolder folder = SubFolder.newSubFolder(name);
		if (softType != null && !"".equals(softType)) {
			TypeDefinitionReference typeDefinitionRef = TypedUtility.getTypeDefinitionReference(softType);
			if (typeDefinitionRef == null)
				throw new Exception("Not found soft type��" + softType);
			folder.setTypeDefinitionReference(typeDefinitionRef);
		}
		folder.setContainer(parentFolder.getContainer());
		FolderHelper.assignLocation(folder, parentFolder);
		if (iba != null && !iba.isEmpty()) {
			LWCUtil.setValueBeforeStore(folder, iba);
		}
		folder = (SubFolder) PersistenceHelper.manager.store(folder);

		return folder;
	}

	/**
	 * get properties from file
	 *
	 * @param propsFile
	 *            file name
	 * @return
	 * @throws Exception
	 */
	public static Properties getProperties(String propsFile) throws Exception {
		Properties props = new Properties();
		FileReader fr = new FileReader(propsFile);
		BufferedReader br = new BufferedReader(fr);
		String line = null;
		while (true) {
			line = br.readLine();
			if (line == null)
				break;
			line = line.trim();
			if (line.startsWith("#"))
				continue;
			int p = line.indexOf("=");
			if (p > 0)
				props.setProperty(line.substring(0, p), line.substring(p + 1));
		}
		fr.close();
		br.close();
		return props;
	}

	/**
	 * get all Container,include WTLibrary and PDMLinkProduct
	 *
	 * @return
	 * @throws Exception
	 */
	public static Vector getWTContainer() throws Exception {
		Vector v = new Vector();
		WTContainer wtc = null;
		QuerySpec qs = new QuerySpec(WTLibrary.class);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements())
			v.addElement(qr.nextElement());
		qs = new QuerySpec(PDMLinkProduct.class);
		qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements())
			v.addElement(qr.nextElement());
		return v;
	}

	/**
	 * copy f1 to f2
	 *
	 * @param f1
	 * @param f2
	 * @throws Exception
	 */
	public static void copyFile(String f1, String f2) throws Exception {
		FileInputStream is = new FileInputStream(f1);
		FileOutputStream f = new FileOutputStream(f2);
		byte[] b = new byte[1024];
		int m = is.read(b);
		while (m != -1) {
			f.write(b, 0, m);
			m = is.read(b);
		}
		f.close();
	}

	/**
	 * get all Descendant(uses) doc from EPMDoc
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static List getDescendants(EPMDocument doc) throws Exception {
		List list = new ArrayList();
		QueryResult qr = EPMStructureHelper.service.navigateUses(doc, null, true);
		while (qr.hasMoreElements()) {
			EPMDocumentMaster master = (EPMDocumentMaster) qr.nextElement();
			EPMDocument subDoc = GenericUtil.getEPMDocument(master.getNumber(), "");
			list.add(subDoc);
			list.addAll(getDescendants(subDoc));
		}
		return list;
	}

	/**
	 * check has any Uses between EPMDoc
	 *
	 * @param doc1
	 * @param doc2
	 * @return
	 * @throws Exception
	 */
	public static boolean isDescendants(EPMDocument doc1, EPMDocument doc2) throws Exception {
		QueryResult qr = EPMStructureHelper.service.navigateUses(doc1, null, true);
		while (qr.hasMoreElements()) {
			EPMDocumentMaster master = (EPMDocumentMaster) qr.nextElement();
			if (master.getNumber().equals(doc2.getNumber())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * get Container by Name
	 *
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public static WTContainer getWTContainer(String name) throws Exception {
		WTContainer wtc = null;
		QuerySpec qs = new QuerySpec(WTLibrary.class);
		SearchCondition sc = new SearchCondition(WTLibrary.class, WTLibrary.NAME, SearchCondition.EQUAL, name);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.size() > 0)
			wtc = (WTContainer) qr.nextElement();
		else {
			qs = new QuerySpec(PDMLinkProduct.class);
			sc = new SearchCondition(PDMLinkProduct.class, PDMLinkProduct.NAME, SearchCondition.EQUAL, name);
			qs.appendWhere(sc);
			qr = PersistenceHelper.manager.find(qs);
			if (qr.size() > 0)
				wtc = (WTContainer) qr.nextElement();
		}
		return wtc;
	}
	
	/**
	 * get Container by Name
	 *
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public static WTLibrary getWTLibrary(String name) throws Exception {
		WTLibrary wtc = null;
		QuerySpec qs = new QuerySpec(WTLibrary.class);
		SearchCondition sc = new SearchCondition(WTLibrary.class, WTLibrary.NAME, SearchCondition.EQUAL, name);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.size() > 0)
			wtc = (WTLibrary) qr.nextElement();
		else {
			qs = new QuerySpec(PDMLinkProduct.class);
			sc = new SearchCondition(PDMLinkProduct.class, PDMLinkProduct.NAME, SearchCondition.EQUAL, name);
			qs.appendWhere(sc);
			qr = PersistenceHelper.manager.find(qs);
			if (qr.size() > 0)
				wtc = (WTLibrary) qr.nextElement();
		}
		return wtc;
	}

	/**
	 * get WTDoc by number and vesion
	 *
	 * @param num
	 * @param ver
	 * @return
	 * @throws Exception
	 */
	public static WTDocument getWTDocument(String num, String ver) throws Exception {
		WTDocument doc = null;
		QuerySpec qs = new QuerySpec(WTDocument.class);
		SearchCondition sc = new SearchCondition(WTDocument.class, WTDocument.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		if (!ver.equals("")) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
//		qs.appendOrderBy(WTDocument.class, "thePersistInfo.createStamp", true);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements())
			doc = (WTDocument) qr.nextElement();
		return doc;
	}

	/**
	 * check the WTPrincipal is member of the role in WTContainer
	 *
	 * @param prin
	 * @param con
	 * @param role
	 * @return
	 * @throws WTException
	 */
	public static boolean isRoleHolder(WTPrincipal prin, WTContainer con, Role role) throws WTException {
		List list = ContainerTeamHelper.service.getContainerTeam((ContainerTeamManaged) con).getAllPrincipalsForTarget(role);
		if (list != null) {
			for (int i = 0; i < list.size(); i++) {
				WTPrincipal wtp = ((WTPrincipalReference) list.get(i)).getPrincipal();
				if (prin.equals(wtp))
					return true;
			}
		}
		return false;
	}

	/**
	 * check the WTPrincipal is member of the role in Team
	 *
	 * @param prin
	 * @param team
	 * @param role
	 * @return
	 * @throws WTException
	 */
	public static boolean isRoleHolder(WTPrincipal prin, Team team, Role role) throws WTException {
		Enumeration enumer = team.getPrincipalTarget(role);
		while (enumer != null && enumer.hasMoreElements()) {
			WTPrincipal wtp = ((WTPrincipalReference) enumer.nextElement()).getPrincipal();
			if (prin.equals(wtp))
				return true;
		}
		return false;
	}

	/**
	 * check the WTPrincipal is member of the role in WTContainer
	 *
	 * @param con
	 * @param role
	 * @return
	 * @throws WTException
	 */
	public static boolean isRoleHolder(WTContainer con, String role) throws WTException {
		return isRoleHolder(SessionMgr.getPrincipal(), con, Role.toRole(role));
	}

	/**
	 * get EPMDoc by number and version
	 *
	 * @param num
	 * @param ver
	 * @return
	 * @throws WTException
	 */
	public static EPMDocument getEPMDocument(String num, String ver) throws WTException {
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		if (!ver.equals("")) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
//		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements())
			doc = (EPMDocument) qr.nextElement();
		return doc;
	}

	/**
	 * get EPMDoc by version and like number
	 *
	 * @param num
	 * @param ver
	 * @return
	 * @throws WTException
	 */
	public static List getEPMDocumentWithLike(String num, String ver) throws WTException {
		List list = new ArrayList();
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NUMBER, SearchCondition.LIKE, num + "%");
		qs.appendWhere(sc);
		if (!ver.equals("")) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
//		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		//log.debug(">>>>>>>>>qr = " + qr);
		while (qr.hasMoreElements()) {
			doc = (EPMDocument) qr.nextElement();
			list.add(doc);
		}
		return list;
	}

	/**
	 * check is PartCentric Processing
	 *
	 * @return
	 */
	public static boolean isPartCentricProcessing() {
		boolean partCentricProcessing = false;
		String keyValue = EpdParams.getEpdParameter("partCentric", "cadxhtmlui", "newworkspace", "false");
		if (keyValue != null && keyValue.equalsIgnoreCase("true"))
			partCentricProcessing = true;
		return partCentricProcessing;
	}

	/**
	 * create a workspace in a continer
	 *
	 * @param wsname
	 * @param container
	 * @return
	 * @throws Exception
	 */
	public static EPMWorkspace createWorkspace(String wsname, WTContainer container) throws Exception {
		WTPartConfigSpec partConfigSpec = WorkspaceConfigSpecUtilities.createWTPartConfigSpec(container);
		EPMDocConfigSpec docConfigSpec = WorkspaceConfigSpecUtilities.createEPMDocConfigSpec(container);
		EPMWorkspace workspace = EPMWorkspace.newEPMWorkspace(wsname, SessionMgr.getPrincipal(), null, partConfigSpec, docConfigSpec, container);
		workspace.setContainer(container);
		workspace.setPopulateRule(EPMPopulateRule.NONE);
		EPMContextHelper.setApplication(EPMApplicationType.toEPMApplicationType("EPM"));
		workspace.setPartCentricProcessing(isPartCentricProcessing());
		workspace = (EPMWorkspace) PersistenceHelper.manager.save(workspace);
		return workspace;
	}

	/**
	 * get a workspace in a continer
	 *
	 * @param con
	 * @return
	 * @throws Exception
	 */
	public static EPMWorkspace getWorkspace(WTContainer con) throws Exception {
		EPMWorkspace[] workspaces = WorkspaceUtilities.getWorkspacesForCurrentUser(con);
		EPMWorkspace ws = null;
		if (workspaces != null && workspaces.length > 0) {
			ws = workspaces[0];
		} else {
			int i = 0;
			String wsnamePrefix = con.getName() + "-" + SessionMgr.getPrincipal().getName();
			String wsname = null;
			while (true) {
				i++;
				if (i == 1)
					wsname = wsnamePrefix;
				else
					wsname = wsnamePrefix + "-" + i;
				ws = WorkspaceUtilities.getWorkspace(wsname);
				if (ws == null) {
					ws = GenericUtil.createWorkspace(wsname, con);
					break;
				} else {
					continue;
				}
			}
		}
		return ws;
	}

	/**
	 * revise WTDocument
	 *
	 * @param doc
	 * @return
	 * @throws WTException
	 */
	public static WTDocument autoReviseWTDocument(WTDocument doc) throws WTException {
		boolean flag = false;
		WTDocument newDoc = null;
		try {
			WTDocument newVersionDoc = (WTDocument) wt.vc.VersionControlHelper.service.newVersion((wt.vc.Versioned) doc);
			String version = ((wt.enterprise.RevisionControlled) newVersionDoc).getVersionIdentifier().getValue();
			newDoc = getWTDocument(doc.getNumber(), version);
			if (newDoc == null) {

				FolderHelper.assignLocation(newVersionDoc, FolderHelper.service.getFolder(doc));
				newDoc = (WTDocument) PersistenceHelper.manager.store(newVersionDoc);
			}
		} catch (Exception e) {
			//log.debug("autoReviseWTDocument Error:" + e.toString());
			e.printStackTrace();
		}
		return newDoc;
	}

	/**
	 * check in a object with comments
	 *
	 * @param w
	 * @param note
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 */
	public static Workable checkin(Workable w, String note) throws WTPropertyVetoException, WTException {
		WTUser user = (WTUser) wt.session.SessionHelper.manager.getPrincipal();
		note = note + "," + (new Date()).toString() + "," + user.getName() + "/" + user.getFullName();
		w = (Workable) PersistenceHelper.manager.refresh(w);
		if (WorkInProgressHelper.isCheckedOut(w))
			w = WorkInProgressHelper.service.checkin(w, note);
		return w;
	}

	/**
	 * check in a object
	 *
	 * @param w
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 */
	public static Workable checkin(Workable w) throws WTPropertyVetoException, WTException {
		return checkin(w, "AutoCheckIn");
	}

	/**
	 * check out a object
	 *
	 * @param w
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 */
	public static Workable checkout(Workable w) throws WTPropertyVetoException, WTException {
		return checkout(w, "AutoCheckOut");
	}

	/**
	 * check out a object with comments
	 *
	 * @param w
	 * @param note
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 */
	public static Workable checkout(Workable w, String note) throws WTPropertyVetoException, WTException {
		if (w instanceof Iterated) {
			Iterated it = (Iterated) w;
			w = (Workable) wt.vc.VersionControlHelper.service.getLatestIteration(it, false);
		}
		Workable wk = null;
		boolean checkoutFlag = WorkInProgressHelper.isCheckedOut(w);
		if (checkoutFlag) {
			if (!WorkInProgressHelper.isWorkingCopy(w)){
				wk = WorkInProgressHelper.service.workingCopyOf(w);
			} else{
				wk = w;
			}
		} else {
			Folder myFolder = WorkInProgressHelper.service.getCheckoutFolder();
			CheckoutLink checkout_lnk = WorkInProgressHelper.service.checkout(w, myFolder, note);
			wk = checkout_lnk.getWorkingCopy();
		}
		return wk;
	}

	/**
	 * get a WTPart by numer,version,view
	 *
	 * @param num
	 * @param ver
	 * @param viewName
	 * @return
	 * @throws Exception
	 */
	public static WTPart getPart(String num, String ver) throws Exception {
		WTPart part = null;
		QuerySpec qs = new QuerySpec(WTPart.class);
		SearchCondition sc = new SearchCondition(WTPart.class, WTPart.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		if (ver!=null && !ver.equals("")) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendOrderBy(WTPart.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements())
			part = (WTPart) qr.nextElement();
		return part;
	}

	/***************************************************************************
	 * set a file as PRIMARY Content
	 *
	 * @param ch
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static ContentHolder linkFile(ContentHolder ch, String filename) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			ch = (ContentHolder) PersistenceHelper.manager.refresh(ch);
			ApplicationData appData = ApplicationData.newApplicationData(ch);
			appData.setRole(ContentRoleType.PRIMARY);
			appData.setFileName(filename.substring(filename.lastIndexOf(File.separator) + 1));
			appData.setUploadedFromPath("");
			File file = new File(filename);
			FileInputStream is = new FileInputStream(file);
			appData = ContentServerHelper.service.updateContent((ContentHolder) ch, appData, is);
			is.close();
			ch = (ContentHolder) ContentServerHelper.service.updateHolderFormat((FormatContentHolder) ch);
			if (!bTran) {
				tran.commit();
				tran = null;
			}
		} catch (Exception e) {
			throw e;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
		return ch;
	}

	public static ContentHolder linkFileAsSecond(ContentHolder ch, String filename) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			ch = (ContentHolder) PersistenceHelper.manager.refresh(ch);
			ApplicationData appData = ApplicationData.newApplicationData(ch);
			appData.setRole(ContentRoleType.SECONDARY);
			appData.setFileName(filename.substring(filename.lastIndexOf(File.separator) + 1));
			appData.setUploadedFromPath("");
			File file = new File(filename);
			FileInputStream is = new FileInputStream(file);
			appData = ContentServerHelper.service.updateContent((ContentHolder) ch, appData, is);
			is.close();
			ch = (ContentHolder) ContentServerHelper.service.updateHolderFormat((FormatContentHolder) ch);
			if (!bTran) {
				tran.commit();
				tran = null;
			}
		} catch (Exception e) {
			throw e;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
		return ch;
	}

	public static ContentHolder replaceFileAsSecond(ContentHolder ch, String filename) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			ch = (ContentHolder) PersistenceHelper.manager.refresh(ch);
			QueryResult qr = ContentHelper.service.getContentsByRole(ch, ContentRoleType.SECONDARY);
			//log.debug("attachAppData.size:" + qr.size());
			while (qr.hasMoreElements()) {
				wt.content.ApplicationData appData = (wt.content.ApplicationData) qr.nextElement();
				ContentServerHelper.service.deleteContent(ch, appData);
			}
			ApplicationData appData = ApplicationData.newApplicationData(ch);
			appData.setRole(ContentRoleType.SECONDARY);
			appData.setCategory("EO_Attachment");
			appData.setFileName(filename.substring(filename.lastIndexOf(File.separator) + 1));
			appData.setUploadedFromPath("");
			File file = new File(filename);
			FileInputStream is = new FileInputStream(file);
			appData = ContentServerHelper.service.updateContent((ContentHolder) ch, appData, is);
			is.close();
			ch = (ContentHolder) ContentServerHelper.service.updateHolderFormat((FormatContentHolder) ch);
			if (!bTran) {
				tran.commit();
				tran = null;
			}
		} catch (Exception e) {
			throw e;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
		return ch;
	}

	/***************************************************************************
	 * set a file as PRIMARY Content
	 *
	 * @param ch
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static ContentHolder attachAppData(ContentHolder ch, ApplicationData data, String category) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			ch = (ContentHolder) PersistenceHelper.manager.refresh(ch);
			// query appdata
			QueryResult qr = ContentHelper.service.getContentsByRole(ch, ContentRoleType.SECONDARY);
			//log.debug("attachAppData.size:" + qr.size());
			while (qr.hasMoreElements()) {
				wt.content.ApplicationData appData = (wt.content.ApplicationData) qr.nextElement();
				// log.debug("category:"+category+" -
				// appData.getCategory():"+appData.getCategory());
				if (appData.getCategory() != null && appData.getCategory().equals(category)) {
					ContentServerHelper.service.deleteContent(ch, appData);
					//log.debug("delete attachAppData ." + appData.getCategory());
				}
			}
			//log.debug("Create new APPData.");
			// create new appdata
			ApplicationData appData = ApplicationData.newApplicationData(ch);
			appData.setRole(ContentRoleType.SECONDARY);
			appData.setFileName(data.getFileName());
			appData.setCategory(category);
			appData.setUploadedFromPath("");
			InputStream is = ContentServerHelper.service.findContentStream(data);
			appData = ContentServerHelper.service.updateContent((ContentHolder) ch, appData, is);
			is.close();
			if (!bTran) {
				tran.commit();
				tran = null;
			}
			//log.debug("create attachAppData end.");
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
		return ch;
	}

	/**
	 * set a file as PRIMARY Content
	 *
	 * @param document
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static WTDocument linkFile(WTDocument document, String filename) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			document = (WTDocument) PersistenceHelper.manager.refresh(document);
			ApplicationData appData = ApplicationData.newApplicationData(document);
			appData.setRole(ContentRoleType.PRIMARY);
			appData.setFileName(filename.substring(filename.lastIndexOf(File.separator) + 1));
			appData.setUploadedFromPath("");
			File file = new File(filename);
			FileInputStream is = new FileInputStream(file);
			appData = ContentServerHelper.service.updateContent((ContentHolder) document, appData, is);
			is.close();
			document = (WTDocument) ContentServerHelper.service.updateHolderFormat((FormatContentHolder) document);
			if (!bTran) {
				tran.commit();
				tran = null;
			}
		} catch (Exception e) {
			throw e;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
		return document;
	}

	/**
	 * create a usagelink between two WTPart
	 *
	 * @param parent
	 * @param child
	 * @param unit
	 * @param amount
	 * @param lineNo
	 * @param occurrence
	 * @return
	 * @throws WTException
	 */
	public static WTPartUsageLink createUsageLink(WTPart parent, WTPart child, String unit, double amount, String lineNo, String occurrence) throws WTException {
		// parent part need checking out before creating the link.
		parent = (WTPart) PersistenceHelper.manager.prepareForModification(parent);
		PersistenceServerHelper.manager.lock(parent, true);
		WTPartMaster master = (WTPartMaster) child.getMaster();
		QuantityUnit quantityUnit = QuantityUnit.toQuantityUnit(unit);
		Quantity quantity = Quantity.newQuantity(amount, quantityUnit);
		WTPartUsageLink usagelink = WTPartUsageLink.newWTPartUsageLink(parent, master);
		try {
			usagelink.setQuantity(quantity);
			if ((lineNo != null) && (lineNo.length() > 0)) {
				LineNumber lineNumber = LineNumber.newLineNumber(Long.parseLong(lineNo));
				usagelink.setLineNumber(lineNumber);
			}
			usagelink = (WTPartUsageLink) PersistenceHelper.manager.store(usagelink);
			// add new occurrence
			if ((occurrence != null) && (occurrence.length() > 0)) {
				PartUsesOccurrence newOccurrence = PartUsesOccurrence.newPartUsesOccurrence(usagelink);
				newOccurrence.setName(occurrence);
				OccurrenceHelper.service.saveUsesOccurrenceAndData(newOccurrence, null);

			}
		} catch (WTPropertyVetoException wpve) {
			throw new WTException(wpve);
		}
		return usagelink;
	}

	/**
	 * get EPMDoc by name ,version
	 *
	 * @param name
	 * @param ver
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument getEPMDocumentByName(String name, String ver) throws Exception {
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NAME, SearchCondition.EQUAL, name);
		qs.appendWhere(sc);
		if (!StringUtil.isNullOrEmpty(ver)) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			doc = (EPMDocument) qr.nextElement();
			if (!doc.getLocation().startsWith(GenericUtil.CONTAINER_ROOT_FOLDER))
				continue;
			break;
		}
		return doc;
	}

	/**
	 * generate Report URL
	 *
	 * @param rt
	 * @return
	 */
	public static String getReportURL(wt.query.template.ReportTemplate rt) {
		String theurl = null;
		try {
			wt.fc.ReferenceFactory rf = new wt.fc.ReferenceFactory();
			String oid = rf.getReferenceString(rt);
			java.util.Properties p = new java.util.Properties();
			p.put("action", "ProduceReport");
			p.put("oid", oid);
			theurl = GatewayURL.buildAuthenticatedURL("wt.enterprise.URLProcessor", "generateForm", p).toExternalForm();
		} catch (WTException wte) {
			wte.printStackTrace();
		}
		return theurl;
	}

	/**
	 * get wtdoc last version
	 *
	 * @param num
	 * @return
	 * @throws Exception
	 */
	public static WTDocument getWTDocument(String num) throws Exception {
		return getWTDocument(num, "");
	}

	/**
	 * get folder by name in Container
	 *
	 * @param path
	 * @param con
	 * @return
	 * @throws WTException
	 */
	public static Folder getFolder(String path, WTContainer con) throws WTException {
		// WTPrincipal curUser = SessionHelper.manager.getPrincipal();
		// WTPrincipal previous = SessionHelper.manager.setAdministrator();
		Folder folder = null;
		// try {
		StringTokenizer tokenizer = new StringTokenizer(path, "/");
		String subPath = "";
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			subPath = subPath + "/" + token;
			try {
				folder = FolderHelper.service.getFolder(subPath, WTContainerRef.newWTContainerRef(con));
			} catch (WTException e) {
				// e.printStackTrace();
				folder = FolderHelper.service.createSubFolder(subPath, WTContainerRef.newWTContainerRef(con));
			}
		}
		// } finally {
		// previous = SessionHelper.manager.setPrincipal(curUser.getName());
		// }
		return folder;
	}

	/**
	 * save wtdoc primary content to local
	 *
	 * @param doc
	 * @param dir
	 * @return
	 * @throws Exception
	 */
	public static String saveToDir(WTDocument doc, String dir) throws Exception {
		String filename = getFileName(doc);
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		saveToFile(doc, dir + filename);
		return filename;
	}

	/**
	 * get name of primary content
	 *
	 * @param doc
	 * @return
	 */
	public static String getFileName(WTDocument doc) {
		return doc.getNumber() + "." + doc.getFormatName();
	}

	/**
	 * get name of primary content
	 *
	 * @param doc
	 * @return
	 */
	public static String getFileName(EPMDocument doc) {
		String filename = doc.getNumber().toLowerCase();
		int dot = filename.indexOf(".");
		if (dot > 0)
			filename = filename.substring(0, dot);
//		String extension = doc.getCADName().toLowerCase();
		String extension = doc.getCADName();
		dot = extension.lastIndexOf(".");
		if (dot > 0)
			extension = extension.substring(dot);
		else
			extension = ".xml";
		filename += extension;
		return filename;
	}

	/**
	 * get name by language
	 *
	 * @param doc
	 * @param lang
	 * @return
	 */
	public static String getFileNameByLang(EPMDocument doc, String lang) {
		String filename = doc.getNumber().toLowerCase();
		int dot = filename.indexOf(".");
		if (dot > 0)
			filename = filename.substring(0, dot);
		String extension = doc.getCADName().toLowerCase();
		dot = extension.lastIndexOf(".");
		if (dot > 0)
			extension = extension.substring(dot);
		else
			extension = ".xml";
		filename += "_" + lang + extension;
		return filename;
	}

	/**
	 * get fullpath of file
	 *
	 * @param filepath
	 * @return
	 */
	public static String duplicatefilename(String filepath) {
		String rt = "";
		String filename = "";
		String extension = "";
		int dot = filepath.lastIndexOf(".");
		if (dot > 0) {
			filename = filepath.substring(0, dot);
			extension = filepath.substring(dot);
		}
		rt = filepath;
		int i = 1;
		while (rt != null) {

			File a = new File(rt);
			if (a.exists()) {
				rt = filename + "_" + String.valueOf(i) + extension;
			} else {
				break;
			}
			i++;
		}
		return rt;
	}

	/**
	 * get primary content file name from a EPMDoc
	 *
	 * @param doc
	 * @return
	 */
	public static String getFileNameByEPMDocName(EPMDocument doc) {
		String rt = "";
		String filename = doc.getName().toLowerCase().replaceAll(" ", "");
		int dot = filename.indexOf(".");
		if (dot > 0)
			filename = filename.substring(0, dot);
		String extension = doc.getCADName().toLowerCase();
		dot = extension.lastIndexOf(".");
		if (dot > 0)
			extension = extension.substring(dot);
		else
			extension = ".xml";

		rt = filename + extension;

		return rt;
	}

	/**
	 * format file name fName = Replace(fName, "/", "") fName = Replace(fName,
	 * "\", "") fName = Replace(fName, "/", "") fName = Replace(fName, ":", "")
	 * fName = Replace(fName, "*", "") fName = Replace(fName, "?", "") fName =
	 * Replace(fName, """", "") fName = Replace(fName, "<", "") fName =
	 * Replace(fName, ">", "") fName = Replace(fName, "!", "")
	 */
	public static String formatFileName(String filename) {
		String formatName = filename.replaceFirst("/", "");
		formatName = formatName.replaceFirst("\\\\", "");
		formatName = formatName.replaceFirst(":", "");
		formatName = formatName.replaceFirst("\\*", "");
		formatName = formatName.replaceFirst("\\?", "");
		formatName = formatName.replaceFirst("\"", "");
		formatName = formatName.replaceFirst("<", "");
		formatName = formatName.replaceFirst(">", "");
		formatName = formatName.replaceFirst("!", "");
		formatName = formatName.replace('&', '-');
		return formatName;
	}

	/**
	 * get primary conetent file name from epmdoc
	 *
	 * @param doc
	 * @return
	 */
	public static String getOfflineFileName(EPMDocument doc) {
		String filename = doc.getName();
		filename = doc.getName() + "(" + doc.getNumber() + ")" + getFileExt(doc);
		filename = formatFileName(filename);
		return filename;
	}

	/**
	 * get primary conetent file extension name from epmdoc
	 *
	 * @param doc
	 * @return
	 */
	public static String getFileExt(EPMDocument doc) {
		String extension = doc.getCADName().toLowerCase();
		int dot = extension.lastIndexOf(".");
		if (dot > 0)
			extension = extension.substring(dot);
		else
			extension = ".xml";
		return extension;
	}

	/**
	 * save primary conetent to local
	 *
	 * @param doc
	 * @param dir
	 * @return
	 * @throws Exception
	 */
	public static String saveToDir(EPMDocument doc, String dir) throws Exception {
		String filename = getFileName(doc);
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		saveToFile(doc, dir + filename);
		return filename;
	}

	/**
	 * save primary conetent to localt
	 *
	 * @param doc
	 * @param dir
	 * @param lang
	 * @return
	 * @throws Exception
	 */
	public static String saveToDirByLang(EPMDocument doc, String dir, String lang) throws Exception {
		String filename = getFileNameByLang(doc, lang);
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		saveToFile(doc, dir + filename);
		return filename;
	}

	/**
	 * save primary conetent to local
	 *
	 * @param doc
	 * @param dir
	 * @return
	 * @throws Exception
	 */
	public static String saveToDirAsEPMName(EPMDocument doc, String dir) throws Exception {
		String filename = getFileNameByEPMDocName(doc).replaceAll(" ", "");
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		filename = duplicatefilename(dir + filename);
		saveToFile(doc, filename);
		//log.debug("GenericUtil:filename=" + filename);
		int dot = filename.lastIndexOf(File.separator);
		return filename.substring(dot + 1);
		// return ;
	}

	/**
	 * save primary conetent to local
	 *
	 * @param doc
	 * @param dir
	 * @return
	 * @throws Exception
	 */
	public static String saveToDirFormatName(EPMDocument doc, String dir) throws Exception {
		String filename = getFileName(doc);
		filename = GenericUtil.formatFileName(filename);
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		saveToFile(doc, dir + filename);
		//log.debug("GenericUtil:filename=" + filename);
		return filename;
	}

	/**
	 * save primary conetent to local
	 *
	 * @param contentHodler
	 * @param filename
	 * @throws Exception
	 */
	public static void saveToFile(FormatContentHolder contentHodler, String filename) throws Exception {
		ContentHolder holder = ContentHelper.service.getContents(contentHodler);
		ContentItem item = ContentHelper.getPrimary((FormatContentHolder) holder);
		InputStream is = ContentServerHelper.service.findContentStream((ApplicationData) item);
		saveToDisk(is, filename);
		is.close();
	}

	public static void saveToDisk(String contents, String filename) throws IOException {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(filename);
			fos.write(contents.getBytes(DEFAULT_CHARSET));
			fos.flush();
		} finally {
			if (fos != null)
				fos.close();
		}
	}

	/**
	 * save primary conetent to local
	 *
	 * @param is
	 * @param filename
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void saveToDisk(InputStream is, String filename) throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream(filename);
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = is.read(buf)) > 0) {
			fos.write(buf, 0, len);
		}
		fos.flush();
		fos.close();
	}

	public static void saveTxtToDisk(InputStream is, String filename) throws FileNotFoundException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		FileWriter writer = new FileWriter(filename);
		PrintWriter bfWriter = new PrintWriter(writer);
		String str = null;
		while ((str = br.readLine()) != null) {
			bfWriter.println(str);
		}
		br.close();
		bfWriter.close();
	}

	/**
	 * revise a Versioned object
	 *
	 * @param currVer
	 * @return
	 * @throws WTException
	 */
	public static Versioned revise(Versioned currVer) throws WTException {
		Versioned newVer = null;
		try {
			Versioned newVersionDoc = VersionControlHelper.service.newVersion((Versioned) currVer, false);
			FolderHelper.assignLocation((FolderEntry) newVersionDoc, FolderHelper.service.getFolder((FolderEntry) currVer));
			newVer = (Versioned) PersistenceHelper.manager.store(newVersionDoc);
		} catch (Exception e) {
			//log.debug("Revise Error:" + e.toString());
			e.printStackTrace();
		}
		return newVer;
	}

	/**
	 * get soft type name
	 *
	 * @param obj
	 * @return
	 * @throws WTException
	 * @throws RemoteException
	 */
	public static String getTypeName(Object obj) throws WTException, RemoteException {
		String type = TypedUtilityServiceHelper.service.getLocalizedTypeName(obj).getLocalizedMessage(WTContext.getContext().getLocale());
		return type;
	}

	/**
	 * get EPMDoc by pdf(PublishedContent)
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument getEPMDocumentByPublishedContent(WTDocument doc) throws Exception {
		QueryResult qrr = PersistenceHelper.manager.navigate(doc, "representable", wt.representation.PublishedContentLink.class);
		EPMDocument epmdoc = null;
		while (qrr.hasMoreElements()) {
			Object obj = qrr.nextElement();
			if (obj instanceof EPMDocument) {
				epmdoc = (EPMDocument) obj;
				break;
			}
		}
		return epmdoc;
	}

	/**
	 * get all pdf files by EPMDoc
	 *
	 * @param epmdoc
	 * @return
	 * @throws Exception
	 */
	public static List getPublishedContent(EPMDocument epmdoc) throws Exception {
		List numbers = new ArrayList();
		QueryResult qr = EPMStructureHelper.service.navigateBothRoles(epmdoc, PublishedContentLink.class);
		while (qr.hasMoreElements()) {
			PublishedContentLink link = (PublishedContentLink) qr.nextElement();
			WTDocument doc = (WTDocument) link.getRoleAObject();
			if (!numbers.contains(doc.getNumber())) {
				numbers.add(doc.getNumber());
			}
		}
		List docs = new ArrayList();
		for (int i = 0; i < numbers.size(); i++) {
			docs.add(GenericUtil.getWTDocument((String) numbers.get(i), ""));
		}
		return docs;
	}

	/**
	 * get ApplicationData from EPMDoc
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static ApplicationData getApplicationData(EPMDocument doc) throws Exception {
		ContentHolder holder = ContentHelper.service.getContents(doc);
		ContentItem item = ContentHelper.getPrimary((FormatContentHolder) holder);
		// ContentServerHelper.service.findContentStream((ApplicationData)item);
		ApplicationData appData = (ApplicationData) item;
		return appData;
	}

	/**
	 * get PrimaryContent download url
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static String getPrimaryContentUrl(EPMDocument doc) throws Exception {
		String url = "/Windchill/servlet/WindchillAuthGW/wt.fv.master.RedirectDownload/redirectDownload/" + doc.getCADName() + "?u8&HttpOperationItem="
				+ StringUtil.replaceAll(getApplicationData(doc).toString(), ":", "%3A") + "&ContentHolder=" + StringUtil.replaceAll(doc.toString(), ":", "%3A")
				+ "&forceDownload=true";
		return url;
	}

	/**
	 * create a DynamicDocument
	 *
	 * @param number
	 * @param name
	 * @param softType
	 * @param filename
	 * @param context
	 * @param folderPath
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createDynamicDocument(String number, String name, String softType, String filename, String context, String folderPath, Map iba)
			throws Exception {
		return createEPMDocument("EPM", "ARBORTEXT", "PUB_COMPOUNDTEXT", number, name, softType, filename, context, folderPath, iba);
	}

	/**
	 * get wtdoc primary content download url
	 *
	 * @author age
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static String getPrimaryContentUrl(WTDocument doc) throws Exception {
		StringBuffer surl = new StringBuffer("/Windchill/servlet/WindchillAuthGW/wt.content.ContentHttp/viewContent/");
		ApplicationData appData = getApplicationData(doc);

		surl.append(appData.getFileName());
		surl.append("?u8&HttpOperationItem=");
		surl.append(StringUtil.replaceAll(getApplicationData(doc).toString(), ":", "%3A"));
		surl.append("&ContentHolder=").append(StringUtil.replaceAll(doc.toString(), ":", "%3A"));
		surl.append("&originalFileName=").append(appData.getFileName());
		surl.append("&forceDownload=true");
		return surl.toString();
	}

	/**
	 * get ApplicationData
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static ApplicationData getApplicationData(ContentHolder doc) throws Exception {
		ContentHolder holder = ContentHelper.service.getContents(doc);
		// ContentHelper.service.getDownloadURL(arg0, arg1)
		ContentItem item = ContentHelper.getPrimary((FormatContentHolder) holder);
		// ContentServerHelper.service.findContentStream((ApplicationData)item);
		ApplicationData appData = (ApplicationData) item;

		return appData;
	}

	/**
	 * create a DynamicDocument
	 *
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param softType
	 * @param filename
	 * @param context
	 * @param folderPath
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createDynamicDocument(String epmDocType, String number, String name, String softType, String filename, String context,
			String folderPath, Map iba) throws Exception {
		return createEPMDocument("EPM", "ARBORTEXT", epmDocType, number, name, softType, filename, context, folderPath, iba);
	}

	/**
	 * create a EPMDoc
	 *
	 * @param epmAppType
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param softType
	 * @param filename
	 * @param context
	 * @param folderPath
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(String epmAppType, String epmAuthType, String epmDocType, String number, String name, String softType,
			String filename, String context, String folderPath, Map iba) throws Exception {
		TypeDefinitionReference typeDefinitionRef = null;
		if (softType != null && !"".equals(softType)) {
			typeDefinitionRef = TypedUtility.getTypeDefinitionReference(softType);
			if (typeDefinitionRef == null)
				throw new Exception("Not found soft type:" + softType);
		}
		Folder folder = null;
		try {
			folder = GenericUtil.getFolder(folderPath, GenericUtil.getWTContainer(context));
		} catch (FolderNotFoundException fnfex) {
			throw new Exception("Error: Not found folder " + folderPath + " in contianer " + context + ".");
		}
		return createEPMDocument(EPMApplicationType.toEPMApplicationType(epmAppType), EPMAuthoringAppType.toEPMAuthoringAppType(epmAuthType), EPMDocumentType
				.toEPMDocumentType(epmDocType), number, name, "", typeDefinitionRef, filename, folder, iba);
	}

	/**
	 * create a EPMDoc
	 *
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param softType
	 * @param filename
	 * @param folder
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(EPMAuthoringAppType epmAuthType, EPMDocumentType epmDocType, String number, String name,
			TypeDefinitionReference softType, String filename, Folder folder, Map iba) throws Exception {
		return createEPMDocument(EPMApplicationType.toEPMApplicationType("EPM"), epmAuthType, epmDocType, number, name, "", softType, filename, folder, iba);
	}

	/**
	 * create a EPMDoc
	 *
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param cadName
	 * @param softType
	 * @param filename
	 * @param folder
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(EPMAuthoringAppType epmAuthType, EPMDocumentType epmDocType, String number, String name, String cadName,
			TypeDefinitionReference softType, String filename, Folder folder, Map iba) throws Exception {
		return createEPMDocument(EPMApplicationType.toEPMApplicationType("EPM"), epmAuthType, epmDocType, number, name, cadName, softType, filename, folder,
				iba);
	}

	/**
	 * create a EPMDoc
	 *
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param cadName
	 * @param softType
	 * @param filename
	 * @param folder
	 * @param iba
	 * @param state
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(EPMAuthoringAppType epmAuthType, EPMDocumentType epmDocType, String number, String name, String cadName,
			TypeDefinitionReference softType, String filename, Folder folder, Map iba, wt.lifecycle.State state) throws Exception {
		return createEPMDocument(EPMApplicationType.toEPMApplicationType("EPM"), epmAuthType, epmDocType, number, name, cadName, softType, filename, folder,
				iba, state);
	}


	/**
	 * update a EPMDoc ContentHolder
	 *
	 * @param doc
	 * @param name
	 * @param filename
	 * @param category
	 * @param iba
	 * @param comments
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument updateHolder(EPMDocument doc, String filename) throws Exception {
		Transaction tran = null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		try {
			if (!bTran) {
				log.debug("===========bTran:"+bTran);
				tran = new Transaction();
				tran.start();
			}
			ContentHolder contentholder = (ContentHolder) doc;
			contentholder = ContentHelper.service.getContents(contentholder);
			List contentListForTarget = ContentHelper.getContentListAll(contentholder);
			for (int i = 0; i < contentListForTarget.size(); i++) {
				ContentItem contentItem = (ContentItem) contentListForTarget.get(i);
				if (contentItem.getRole().toString().equals("PRIMARY")) {
					ContentServerHelper.service.deleteContent(contentholder, contentItem);
					break;
				}
			}
			ApplicationData appData = ApplicationData.newApplicationData(doc);
			appData.setRole(ContentRoleType.PRIMARY);
			appData.setFileName(doc.getCADName());
			StandardContentService.setFormat(filename, appData);
			appData.setCategory("");
			FileInputStream is = new FileInputStream(filename);
			appData = ContentServerHelper.service.updateContent(doc, appData, is);
			is.close();
			doc = (EPMDocument) ContentServerHelper.service.updateHolderFormat(doc);
			if (!bTran) {
				tran.commit();
				tran = null;
			}
			return doc;
		} catch (Exception e) {
			e.printStackTrace();
			return doc;
		}finally{
			if (tran != null){
				tran.rollback();
			}
		}
	}


	/**
	 * create a EPMDoc
	 *
	 * @param epmAppType
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param cadName
	 * @param softType
	 * @param filename
	 * @param folder
	 * @param iba
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(EPMApplicationType epmAppType, EPMAuthoringAppType epmAuthType, EPMDocumentType epmDocType, String number,
			String name, String cadName, TypeDefinitionReference softType, String filename, Folder folder, Map iba) throws Exception {
		EPMContextHelper.setApplication(epmAppType);
		EPMDocument doc = EPMDocument.newEPMDocument(number, name, epmAuthType, epmDocType);
		if (softType != null) {
			doc.setTypeDefinitionReference(softType);
		}
		String cadNameTemp = cadName;
		if (cadName == null || cadName.equalsIgnoreCase("")) {
//			cadNameTemp = filename.substring(filename.lastIndexOf(File.separator) + 1);
			cadNameTemp = number + filename.substring(filename.lastIndexOf(".")).toLowerCase();
		}
		doc.setCADName(cadNameTemp);
		doc.setDocSubType(EPMDocSubType.getEPMDocSubTypeDefault());
		if (folder!=null) {
			doc.setContainer(folder.getContainer());
			FolderHelper.assignLocation(doc, folder);
		}
		if (iba != null && !iba.isEmpty()) {
			LWCUtil.setValueBeforeStore(doc, iba);
		}
		doc = (EPMDocument) PersistenceHelper.manager.store(doc);

		doc = (EPMDocument) GenericUtil.linkFile(doc, filename);
		return doc;
	}

	/**
	 * create a EPMDoc
	 *
	 * @param epmAppType
	 * @param epmAuthType
	 * @param epmDocType
	 * @param number
	 * @param name
	 * @param cadName
	 * @param softType
	 * @param filename
	 * @param folder
	 * @param iba
	 * @param state
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument createEPMDocument(EPMApplicationType epmAppType, EPMAuthoringAppType epmAuthType, EPMDocumentType epmDocType, String number,
			String name, String cadName, TypeDefinitionReference softType, String filename, Folder folder, Map iba, wt.lifecycle.State state) throws Exception {
		EPMContextHelper.setApplication(epmAppType);
		EPMDocument doc = EPMDocument.newEPMDocument(number, name, epmAuthType, epmDocType);
		if (softType != null) {
			doc.setTypeDefinitionReference(softType);
		}
		String cadNameTemp = cadName;
		if (cadName == null || cadName.equalsIgnoreCase("")) {
			cadNameTemp = filename.substring(filename.lastIndexOf(File.separator) + 1);
		}

		doc.setCADName(cadNameTemp);
		doc.setDocSubType(EPMDocSubType.getEPMDocSubTypeDefault());
		doc.setContainer(folder.getContainer());
		FolderHelper.assignLocation(doc, folder);

		// set state
		wt.lifecycle.LifeCycleState lc = wt.lifecycle.LifeCycleState.newLifeCycleState();
		lc.setState(state);
		doc.setState(lc);
		if (iba != null && !iba.isEmpty()) {
			LWCUtil.setValueBeforeStore(doc, iba);
		}
		// wt.lifecycle.LifeCycleHelper.service.setLifeCycleState(doc,state);
		doc = (EPMDocument) PersistenceHelper.manager.store(doc);

		doc = (EPMDocument) GenericUtil.linkFile(doc, filename);
		return doc;
	}

	/**
	 * get a EPMDoc by CAD
	 *
	 * @param cadname
	 * @return
	 * @throws WTException
	 */
	public static EPMDocument getEPMDocumentByCADName(String cadname) throws WTException {
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		qs.appendWhere(new SearchCondition(new KeywordExpression("lower(A0B.cadname)"), SearchCondition.EQUAL, new KeywordExpression("'"+cadname.toLowerCase()+"'")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			doc = (EPMDocument) qr.nextElement();
			if (!doc.getLocation().startsWith(GenericUtil.CONTAINER_ROOT_FOLDER))
				continue;
			break;
		}
		return doc;
	}

	/**
	 * create a ReferenceLink between two EPMDocument
	 *
	 * @param cadname1
	 * @param cadname2
	 * @throws Exception
	 */
	// public static void createEPMReferenceLink(String cadname1, String
	// cadname2)
	// throws Exception {
	// EPMDocument doc1 = getEPMDocumentByCADName(cadname1);
	// EPMDocument doc2 = getEPMDocumentByCADName(cadname2);
	// if (doc1 == null || doc2 == null)
	// return;
	// EPMReferenceLink link = EPMReferenceLink.newEPMReferenceLink(doc1,
	// (DocumentMaster) doc2.getMaster());
	// PersistenceServerHelper.manager.insert(link);
	// }
	/**
	 * create a ReferenceLink between two EPMDocument
	 *
	 * @param doc1
	 * @param doc2
	 * @throws Exception
	 */
	// public static void createEPMReferenceLink(EPMDocument doc1, EPMDocument
	// doc2)
	// throws Exception {
	// if (doc1 == null || doc2 == null)
	// return;
	// EPMReferenceLink link = EPMReferenceLink.newEPMReferenceLink(doc1,
	// (DocumentMaster) doc2.getMaster());
	// link.setReferenceType(EPMReferenceType.toEPMReferenceType("INTERNAL"));
	// PersistenceServerHelper.manager.insert(link);
	// }
	/**
	 * get all Reference object
	 *
	 * @param epmdoc
	 * @return
	 * @throws Exception
	 */
	public static List getReferences(EPMDocument epmdoc) throws Exception {
		List numbers = new ArrayList();
		QueryResult qr = EPMStructureHelper.service.navigateReferences(epmdoc, null, true);
		while (qr.hasMoreElements()) {
			EPMDocumentMaster master = (EPMDocumentMaster) qr.nextElement();
			if (!numbers.contains(master.getNumber())) {
				numbers.add(master.getNumber());
			}
		}
		List references = new ArrayList();
		for (int i = 0; i < numbers.size(); i++) {
			references.add(GenericUtil.getEPMDocument((String) numbers.get(i), ""));
		}
		return references;
	}

	/**
	 * get all ReferenceBy object
	 *
	 * @param epmdoc
	 * @return
	 * @throws Exception
	 */
	public static List getReferenceBy(EPMDocument epmdoc) throws Exception {
		List numbers = new ArrayList();
		QueryResult qr = EPMStructureHelper.service.navigateReferencedBy((DocumentMaster) epmdoc.getMaster(), null, true);
		while (qr.hasMoreElements()) {
			EPMDocument master = (EPMDocument) qr.nextElement();
			if (!numbers.contains(master.getNumber())) {
				numbers.add(master.getNumber());
			}
		}
		List references = new ArrayList();
		for (int i = 0; i < numbers.size(); i++) {
			references.add(GenericUtil.getEPMDocument((String) numbers.get(i), ""));
		}
		return references;
	}

	/**
	 * get primary Content
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static String getTextContent(EPMDocument doc) throws Exception {
		//log.debug("GenericUtil: begin to get TextContent");
		ContentHolder holder = ContentHelper.service.getContents(doc);
		//log.debug("GenericUtil: 1");
		ContentItem item = ContentHelper.getPrimary((FormatContentHolder) holder);
		//log.debug("GenericUtil: 2");
		InputStream is = ContentServerHelper.service.findContentStream((ApplicationData) item);
		//log.debug("GenericUtil: end to get TextContent");
		return getString(is);
	}

	/**
	 * get foramted filename
	 *
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static String getString(String filename) throws Exception {
		InputStream is = new FileInputStream(filename);
		String content = getString(is);
		is.close();
		return content;
	}

	/**
	 * get foramted filename
	 *
	 * @param f
	 * @return
	 * @throws Exception
	 */
	public static String getString(File f) throws Exception {
		InputStream is = new FileInputStream(f);
		String content = getString(is);
		is.close();
		return content;
	}

	/**
	 * get foramted filename
	 *
	 * @param is
	 * @return
	 * @throws Exception
	 */
	public static String getString(InputStream is) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = is.read(buf)) > 0) {
			baos.write(buf, 0, len);
		}
		baos.flush();
		String content = baos.toString(DEFAULT_CHARSET);
		baos.close();
		return content;
	}

	/**
	 * rename a epmdoc
	 *
	 * @param epmdoc
	 * @param newName
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument rename(EPMDocument epmdoc, String newName) throws Exception {
		if (newName == null)
			return epmdoc;
		newName = newName.trim();
		if (!StringUtil.isNullOrEmpty(newName) && !newName.equals(epmdoc.getName())) {
			Identified aIdentified = (Identified) epmdoc.getMaster();
			log.debug("============aIdentified:"+aIdentified);
			EPMDocumentMasterIdentity aEPMDocumentMasterIdentity = (EPMDocumentMasterIdentity) aIdentified.getIdentificationObject();
			aEPMDocumentMasterIdentity.setName(newName);
			IdentityHelper.service.changeIdentity(aIdentified, aEPMDocumentMasterIdentity);
			epmdoc = (EPMDocument) PersistenceHelper.manager.refresh(epmdoc);
		}
		return epmdoc;
	}

	/**
	 * rename a wtdoc
	 *
	 * @param wtdoc
	 * @param newName
	 * @return
	 * @throws Exception
	 */
	public static WTDocument rename(WTDocument wtdoc, String newName) throws Exception {
		if (newName == null)
			return wtdoc;
		newName = newName.trim();
		if (!StringUtil.isNullOrEmpty(newName) && !newName.equals(wtdoc.getName())) {
			Identified aIdentified = (Identified) wtdoc.getMaster();
			WTDocumentMasterIdentity aEPMDocumentMasterIdentity = (WTDocumentMasterIdentity) aIdentified.getIdentificationObject();
			aEPMDocumentMasterIdentity.setName(newName);
			IdentityHelper.service.changeIdentity(aIdentified, aEPMDocumentMasterIdentity);
			wtdoc = (WTDocument) PersistenceHelper.manager.refresh(wtdoc);
		}
		return wtdoc;
	}

	/**
	 * get a Object info URL
	 *
	 * @param objtype
	 * @param number
	 * @return
	 * @throws Exception
	 */
	public static String getObjUrl(String objtype, String number) throws Exception {
		if (EPMDocument.class.getName().equals(objtype)) {
			return getObjUrl(getEPMDocument(number, ""));
		} else if (WTDocument.class.getName().equals(objtype)) {
			return getObjUrl(getWTDocument(number, ""));
		}
		return null;
	}

	/**
	 * get a Object info URL
	 *
	 * @param obj
	 * @return
	 */
	public static String getObjUrl(Object obj) {
		return getObjUrl(obj, "ObjProps");
	}

	/**
	 * get a Object info URL
	 *
	 * @param obj
	 * @param action
	 * @return
	 */
	public static String getObjUrl(Object obj, String action) {
		if (obj == null)
			return "";
		String urlLink = "";
		try {
			HashMap hashmap = new HashMap();
			hashmap.put("Action", action);
			hashmap.put("oid", (new ReferenceFactory()).getReferenceString((WTObject) obj));
			URLFactory urlfactory = null;
			try {
				urlfactory = (URLFactory) MethodContext.getContext().get("URLFactory");
			} catch (Exception ex) {
			}
			if (urlfactory == null)
				urlfactory = new URLFactory();
			urlLink = GatewayServletHelper.buildAuthenticatedHREF(urlfactory, "wt.enterprise.URLProcessor", "generateForm", hashmap);
			urlLink = trimBaseHostUrl(urlLink);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return urlLink;
	}

	/**
	 * get a URL exclude host name
	 *
	 * @param theUrl
	 * @return
	 */
	public static String trimBaseHostUrl(String theUrl) {
		if (theUrl == null || theUrl.length() == 0)
			return "";
		String windchill = "/WINDCHILL/";
		int nIndex = theUrl.toUpperCase().indexOf(windchill);
		if (nIndex > 0)
			theUrl = theUrl.substring(nIndex);
		return theUrl;
	}

	/**
	 * move a object to other foler
	 *
	 * @param obj
	 * @param folder
	 * @return
	 * @throws Exception
	 */
	public static FolderEntry changeFolder(FolderEntry obj, Folder folder) throws Exception {
		if (FolderHelper.service.getFolder(obj).equals(folder))
			return obj;
		obj = FolderHelper.service.changeFolder(obj, folder);
		return (FolderEntry) PersistenceHelper.manager.refresh(obj);
	}

	/**
	 * get the last version EPMDoc
	 *
	 * @param num
	 * @return
	 * @throws WTException
	 */
	public static EPMDocument getEPMDocument(String num) throws WTException {
		return getEPMDocument(num, "");
	}

	/**
	 * check any Child is check out
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static boolean hasCheckedOutChild(EPMDocument doc) throws Exception {
		QueryResult qr = EPMStructureHelper.service.navigateUses(doc, null, true);
		boolean flag = false;
		while (qr.hasMoreElements()) {
			EPMDocumentMaster master = (EPMDocumentMaster) qr.nextElement();
			EPMDocument subDoc = GenericUtil.getEPMDocument(master.getNumber(), "");
			flag = WorkInProgressHelper.isCheckedOut(subDoc);
			if (flag)
				break;
			flag = hasCheckedOutChild(subDoc);
		}
		return flag;
	}

	/**
	 * get soft type id
	 *
	 * @param obj
	 * @return
	 * @throws WTException
	 * @throws RemoteException
	 */
	public static String getTypeId(Object obj) throws WTException, RemoteException {
		return TypedUtilityServiceHelper.service.getExternalTypeIdentifier(obj).toString();
	}

	/**
	 * create a baseline
	 *
	 * @param baselineName
	 * @param description
	 * @param folder
	 * @return
	 * @throws Exception
	 */
	public static ManagedBaseline createBaseLine(String number, String baselineName, String description, Folder folder) throws WTException, WTPropertyVetoException {
		ManagedBaseline baseline = ManagedBaseline.newManagedBaseline();
		if (number!=null && !number.equals("")) {
			baseline.setNumber(number);
		}
		baseline.setName(baselineName);
		baseline.setDescription(description);
		FolderHelper.assignLocation(baseline, folder);
		baseline = (ManagedBaseline) PersistenceHelper.manager.save(baseline);
		return baseline;
	}

	/**
	 * 根据编号查询基线
	 * @param num
	 * @return
	 * @throws WTException
	 */
	public static ManagedBaseline getBaseline(String num) throws WTException {
		ManagedBaseline bl = null;
		QuerySpec qs = new QuerySpec(ManagedBaseline.class);
		SearchCondition sc = new SearchCondition(ManagedBaseline.class,
				ManagedBaseline.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements()) {
			bl = (ManagedBaseline) qr.nextElement();
		}
		return bl;
	}

	/**
	 * put a object into a baseline
	 *
	 * @param baseline
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static Baseline addObjectToBaseline(Baseline baseline, EPMDocument doc) throws Exception {
		try {
			if (!BaselineHelper.service.isInBaseline(doc, baseline)) {
				baseline = BaselineHelper.service.addToBaseline(doc, baseline);
			}
			QueryResult qr = EPMStructureHelper.service.navigateUses(doc, null, true);
			while (qr.hasMoreElements()) {
				EPMDocumentMaster master = (EPMDocumentMaster) qr.nextElement();
				EPMDocument subDoc = getEPMDocument(master.getNumber(), "");
				baseline = addObjectToBaseline(baseline, subDoc);
			}
		} catch (Exception wte) {
			wte.printStackTrace();
			throw wte;
		}
		return baseline;
	}
	
	/**
	 * put a object into a baseline
	 *
	 * @param baseline
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static Baseline addObjectToBaseline(Baseline baseline, List<EPMDocument> listObject) throws Exception {
		EPMDocument doc = null;
		try {
			for (int i = 0; i < listObject.size(); i++) {
				doc = listObject.get(i);
				if (!BaselineHelper.service.isInBaseline(doc, baseline)) {
					baseline = BaselineHelper.service.addToBaseline(doc, baseline);
				}
			}
		} catch (Exception wte) {
			wte.printStackTrace();
			throw wte;
		}
		return baseline;
	}
	

	/**
	 * get all DependsOn wtdoc of this
	 *
	 * @param doc
	 * @return
	 * @throws Exception
	 */
	public static List getWTDocumentsByWTDocument(WTDocument doc) throws Exception {
		List docList = new ArrayList();
		QueryResult v = WTDocumentHelper.service.getDependsOnWTDocuments(doc, false);
		Vector vector = v.getObjectVector().getVector();
		for (int k = 0; k < vector.size(); k++) {
			WTDocumentDependencyLink docLink = (WTDocumentDependencyLink) vector.get(k);
			/*
			 * Object[] o = docLink.getAllObjects(); for(int m = 0;m <
			 * o.length;m++) { if(o[m] instanceof WTDocument) { WTDocument doc1 =
			 * (WTDocument)o[m]; docList.add(doc1); } }
			 */
			docList.add(docLink.getDependsOn());
		}
		return docList;
	}

	/**
	 * get the Effect objects
	 *
	 * @param wtco
	 * @return
	 * @throws Exception
	 */
	public static List getEffect(WTChangeOrder2 wtco) throws Exception {
		List list = new ArrayList();
		QueryResult qr = ChangeHelper2.service.getChangeablesBefore(wtco);
		while (qr.hasMoreElements()) {
			// EPMDocument cab=(EPMDocument)qr.nextElement();
			list.add(qr.nextElement());
		}
		return list;
	}

	/**
	 * get the Effect objects
	 *
	 * @param wtco
	 * @return
	 * @throws Exception
	 */
	public static List getEffect(WTChangeActivity2 wtco) throws Exception {
		List list = new ArrayList();
		QueryResult qr = ChangeHelper2.service.getChangeablesBefore(wtco);
		while (qr.hasMoreElements()) {
			// EPMDocument cab=(EPMDocument)qr.nextElement();
			list.add(qr.nextElement());
		}
		return list;
	}

	/**
	 * get objects by soft Type
	 *
	 * @param softtype
	 * @return
	 * @throws Exception
	 */
	public static List queryEPMDocumentBySofttype(String softtype) throws Exception {
		QuerySpec qs = new QuerySpec();
		int docIndex = qs.appendClassList(EPMDocument.class, true);
		int defIndex = qs.appendClassList(WTTypeDefinition.class, false);
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.IDA2TYPEDEFINITIONREFERENCE"), SearchCondition.EQUAL, new KeywordExpression("A1.ida2a2")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A1.name"), SearchCondition.EQUAL, new KeywordExpression("'" + softtype + "'")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.createstampa2"), true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List list = new ArrayList();
		List numbers = new ArrayList();

		while (qr.hasMoreElements()) {
			Object[] obj = (Object[]) qr.nextElement();
			EPMDocument doc = (EPMDocument) obj[0];
			if (!numbers.contains(doc.getNumber())) {
				numbers.add(doc.getNumber());
				list.add(doc);
			}
		}
		return list;
	}
	
	/**
	 * get objects by soft Type
	 *
	 * @param softtype
	 * @return
	 * @throws Exception
	 */
	public static List queryEPMDocumentBySofttypeAndContainer(String softtype,WTLibrary wtLibrary) throws Exception {
		QuerySpec qs = new QuerySpec();
		qs.appendClassList(EPMDocument.class, true);
		qs.appendClassList(WTTypeDefinition.class, false);
		qs.appendClassList(EPMDocumentMaster.class, false);
		long ida2a2 = PersistenceHelper.getObjectIdentifier(wtLibrary).getId();
		softtype = softtype.substring(softtype.lastIndexOf("|")+1);
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.IDA2TYPEDEFINITIONREFERENCE"), SearchCondition.EQUAL, new KeywordExpression("A1.ida2a2")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.IDA3MASTERREFERENCE"), SearchCondition.EQUAL, new KeywordExpression("A2.IDA2A2")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A1.name"), SearchCondition.EQUAL, new KeywordExpression("'" + softtype + "'")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A2.IDA3CONTAINERREFERENCE"), SearchCondition.EQUAL, new KeywordExpression("'" + ida2a2 + "'")));
		qs.appendAnd();	
		qs.appendWhere(new SearchCondition(new KeywordExpression("A2.CLASSNAMEKEYCONTAINERREFEREN"), SearchCondition.EQUAL, new KeywordExpression("'" + wtLibrary.getClass().getName() + "'")));
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.createstampa2"), true));
		log.info("-sql-:"+qs.toString());
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List list = new ArrayList();
		List numbers = new ArrayList();

		while (qr.hasMoreElements()) {
			Object[] obj = (Object[]) qr.nextElement();
			EPMDocument doc = (EPMDocument) obj[0];
			if (!numbers.contains(doc.getNumber())) {
				numbers.add(doc.getNumber());
				list.add(doc);
			}
		}
		return list;
	}

	/**
	 * update the primary content
	 *
	 * @param newDoc
	 * @param filename
	 * @return
	 * @throws WTException
	 * @throws PropertyVetoException
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static EPMDocument changeDocumentPrimary(EPMDocument newDoc, String filename) throws WTException, PropertyVetoException, FileNotFoundException,
			IOException {
		ContentHolder contentholder = (ContentHolder) newDoc;

		contentholder = ContentHelper.service.getContents(contentholder);
		Vector contentListForTarget = ContentHelper.getContentListAll(contentholder);
		for (int i = 0; i < contentListForTarget.size(); i++) {
			ContentItem contentItem = (ContentItem) contentListForTarget.elementAt(i);
			if (contentItem.getRole().toString().equals("PRIMARY")) {
				//log.debug("Delete Current Primary content!");
				ContentServerHelper.service.deleteContent(contentholder, contentItem);
				break;
			}
		}

		ApplicationData applicationdata = ApplicationData.newApplicationData(contentholder);
		applicationdata.setRole(ContentRoleType.toContentRoleType("PRIMARY"));
		applicationdata.setCategory("GENERAL");
		applicationdata = ContentServerHelper.service.updateContent(contentholder, applicationdata, filename);
		newDoc = (EPMDocument) PersistenceHelper.manager.refresh(newDoc);
		return newDoc;

	}

	/**
	 * get all file in a folder
	 *
	 * @param toDir
	 * @return
	 * @throws Exception
	 */
	public static List getFilesByPath(String toDir) throws Exception {
		List fileList = new ArrayList();
		File dir = new File(toDir);
		File[] files = dir.listFiles();
		String podOrderDir = toDir;
		//log.debug(podOrderDir);
		//log.debug("size:" + files.length);
		for (int i = 0; i < files.length; i++) {

			if (files[i].isDirectory()) {
				podOrderDir = files[i].getPath();
				fileList.addAll(getFilesByPath(podOrderDir));
			} else {
				fileList.add(toDir + File.separator + files[i].getName());
			}
		}

		return fileList;
	}

	/**
	 * get EPMDocument by oid
	 *
	 * @param oid
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument getEPMDocumentByOid(String oid) throws Exception {
		return (EPMDocument) GenericUtil.REF_FACTORY.getReference(oid).getObject();
	}

	/**
	 * get all Released epmdoc by number
	 *
	 * @param num
	 * @return
	 * @throws Exception
	 */
	public static List queryReleaseEPMDocumentsByNumber(String num) throws Exception {
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(EPMDocument.class, EPMDocument.LIFE_CYCLE_STATE, SearchCondition.EQUAL, "RELEASED"));
		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List l = new ArrayList();
		while (qr.hasMoreElements()) {
			doc = (EPMDocument) qr.nextElement();
			l.add(doc);
		}
		return l;
	}

	/**
	 * get all Released epmdoc by number,state
	 *
	 * @param num
	 * @param state
	 * @return
	 * @throws Exception
	 */
	public static List queryEPMDocumentsByNumberState(String num, String state) throws Exception {
		EPMDocument doc = null;
		QuerySpec qs = new QuerySpec(EPMDocument.class);
		SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NUMBER, SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		qs.appendAnd();

		qs.appendWhere(new SearchCondition(EPMDocument.class, EPMDocument.LIFE_CYCLE_STATE, SearchCondition.EQUAL, state));
		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List l = new ArrayList();
		while (qr.hasMoreElements()) {
			doc = (EPMDocument) qr.nextElement();
			l.add(doc);
		}
		return l;
	}

	/**
	 * get the pre version by number
	 *
	 * @param num
	 * @return
	 * @throws Exception
	 */
	public static EPMDocument getPreFinalEPMDocumentByNumber(String num) throws Exception {
		List l = queryEPMDocumentsByNumberState(num, "Final");
		if (l.size() > 0) {
			return (EPMDocument) l.get(0);
		} else {
			return null;
		}

	}

	/**
	 * get the last baseline
	 *
	 * @param doc
	 * @return
	 * @throws WTException
	 */
	public static ManagedBaseline getEPMLastedBaseLine(EPMDocument doc) throws WTException {
		ManagedBaseline baseline = null;
		wt.fc.QueryResult qr = wt.vc.baseline.BaselineHelper.service.getBaselines(doc);
		while (qr.hasMoreElements()) {
			Object obj = qr.nextElement();
			if (!(obj instanceof wt.vc.baseline.ManagedBaseline))
				continue;
			wt.vc.baseline.ManagedBaseline b1 = (wt.vc.baseline.ManagedBaseline) obj;
			if (baseline != null) {
				if (baseline.getCreateTimestamp().before(b1.getCreateTimestamp())) {
					baseline = b1;
				}
			} else {
				baseline = b1;
			}
		}
		return baseline;
	}

	/**
	 * get epmdocs by cadname,cadnumber
	 *
	 * @param cadname
	 * @param cadnumber
	 * @return
	 * @throws Exception
	 */
	public static ArrayList searchEPMDocuments(String cadname, String cadnumber) throws Exception {

		if (StringUtil.isNullOrEmpty(cadname) && StringUtil.isNullOrEmpty(cadnumber)) {
			return null;
		}

		QuerySpec qs = new QuerySpec(EPMDocument.class);
		qs.appendOpenParen();
		if (!StringUtil.isNullOrEmpty(cadnumber)) {
			SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.NUMBER, SearchCondition.LIKE, cadnumber + "%");
			qs.appendWhere(sc);
			qs.appendAnd();
		}

		if (!StringUtil.isNullOrEmpty(cadname)) {
			SearchCondition sc = new SearchCondition(EPMDocument.class, EPMDocument.CADNAME, SearchCondition.LIKE, cadname + "%");
			qs.appendWhere(sc);
			qs.appendAnd();
		}

		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendCloseParen();
		qs.appendOrderBy(EPMDocument.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		ArrayList list = new ArrayList();
		List numbers = new ArrayList();

		while (qr.hasMoreElements()) {
			EPMDocument doc = (EPMDocument) qr.nextElement();
			if (!numbers.contains(doc.getNumber())) {
				numbers.add(doc.getNumber());
				list.add(doc);
			}
		}
		return list;
	}

	/**
	 * get the last reference epmdoc
	 *
	 * @param doc
	 * @return reference epmdocuments
	 * @throws WTException
	 */
	public static EPMDocument getLastedEPMReferenceDoc(EPMDocument doc) throws WTException {
		QueryResult res1 = PersistenceHelper.manager.navigate(doc, "references", wt.epm.structure.EPMReferenceLink.class);
		EPMDocumentMaster returnDocMaster = null;
		while (res1.hasMoreElements()) {
			Object obj = res1.nextElement();
			if (obj instanceof EPMDocumentMaster) {
				EPMDocumentMaster master = (EPMDocumentMaster) obj;
				if (returnDocMaster == null) {
					returnDocMaster = master;
				} else {
					if (returnDocMaster.getCreateTimestamp().before(master.getCreateTimestamp())) {
						returnDocMaster = master;
					}
				}
			}
		}
		if (returnDocMaster != null) {
			return getEPMDocument(returnDocMaster.getNumber());
		} else {
			return null;
		}
	}

	/**
	 * get wtdocs by cadname,cadnumber
	 *
	 * @param cadname
	 * @param cadnumber
	 * @return
	 * @throws Exception
	 */
	public static ArrayList searchWTDocuments(String cadname, String cadnumber) throws Exception {

		if (StringUtil.isNullOrEmpty(cadname) && StringUtil.isNullOrEmpty(cadnumber)) {
			return null;
		}

		QuerySpec qs = new QuerySpec(WTDocument.class);

		if (!StringUtil.isNullOrEmpty(cadnumber)) {
			SearchCondition sc = new SearchCondition(WTDocument.class, WTDocument.NUMBER, SearchCondition.LIKE, cadnumber + "%");
			qs.appendWhere(sc);
			qs.appendAnd();
		}

		if (!StringUtil.isNullOrEmpty(cadname)) {
			SearchCondition sc = new SearchCondition(WTDocument.class, WTDocument.NAME, SearchCondition.LIKE, cadname + "%");
			qs.appendWhere(sc);
			qs.appendAnd();
		}

		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		qs.appendOrderBy(WTDocument.class, "thePersistInfo.createStamp", true);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		ArrayList list = new ArrayList();
		List numbers = new ArrayList();
		while (qr.hasMoreElements()) {
			WTDocument doc = (WTDocument) qr.nextElement();
			if (!numbers.contains(doc.getNumber())) {
				numbers.add(doc.getNumber());
				list.add(doc);
			}
		}
		return list;
	}

	/**
	 *
	 * @param ch
	 * @return
	 * @throws WTException
	 * @throws ObjectNoLongerExistsException
	 */

	public static List<File> getAttachedFiles(ContentHolder ch) throws Exception {
		List<File> files = new ArrayList();
		// query appdata
		WTProperties wtproperties = WTProperties.getLocalProperties();
		String codebase = wtproperties.getProperty("wt.home") + "/codebase";
		String tempFolder = codebase + File.separator + "temp" + File.separator + System.currentTimeMillis() + File.separator;
		File f = new File(tempFolder);
		if (!f.exists()) {
			f.mkdirs();
		}
		QueryResult qr = ContentHelper.service.getContentsByRole(ch, ContentRoleType.SECONDARY);
//		log.debug("attachAppData.size:" + qr.size());
		while (qr.hasMoreElements()) {
			wt.content.ApplicationData appData = (wt.content.ApplicationData) qr.nextElement();
			InputStream is = ContentServerHelper.service.findContentStream(appData);
			String appFile = tempFolder + appData.getFileName();
//			log.debug("get appdata:" + appFile);
			saveTxtToDisk(is, appFile);
			files.add(new File(appFile));
			is.close();
		}
		return files;
	}

	/**
	 *
	 * @param ch
	 * @return
	 * @throws WTException
	 * @throws ObjectNoLongerExistsException
	 */

	public static List<File> saveAttachedFiles(ContentHolder ch, String folderpath, String filePre) throws Exception {
		List<File> files = new ArrayList();
		// query appdata
		WTProperties wtproperties = WTProperties.getLocalProperties();
		String codebase = wtproperties.getProperty("wt.home") + "/codebase";
		if (!folderpath.endsWith("/") && !folderpath.endsWith(File.separator)) {
			folderpath = folderpath + File.separator;
		}
		File f = new File(folderpath);
		if (!f.exists()) {
			f.mkdirs();
		}
		QueryResult qr = ContentHelper.service.getContentsByRole(ch, ContentRoleType.SECONDARY);
//		log.debug("attachAppData.size:" + qr.size());
		while (qr.hasMoreElements()) {
			wt.content.ApplicationData appData = (wt.content.ApplicationData) qr.nextElement();
			InputStream is = ContentServerHelper.service.findContentStream(appData);
			String appFile = folderpath + filePre + appData.getFileName();
			saveByteFile(is,appFile);
//			saveTxtToDisk(is, appFile);
			files.add(new File(appFile));
		}
		return files;
	}

	/**
	 *
	 * @return
	 */
	public static int genRandom() {
		int rnumber = (int) (Math.random() * 1000000);
		return rnumber;

	}
	/*
	 * Save byte file to local.
	 */
	public static void saveByteFile(InputStream is, String filePath) throws FileNotFoundException{
		FileOutputStream fout = new FileOutputStream(filePath);
		DataOutputStream dout = new DataOutputStream(fout);
		int temp;
		try {
			while ((temp = is.read()) != -1) {
				dout.write(temp);
			}
		} catch (IOException ex1) {
			ex1.printStackTrace();
		} finally {
			try {
				is.close();
				fout.close();
				dout.close();
			} catch (IOException ex2) {
				ex2.printStackTrace();
			}
		}
	}


	public static void createFolder(String path){
		File dic = new File(path);
		if(!dic.exists()){
			dic.mkdirs();
		}
	}

	// 没有充分考虑文档挂多个文件的问题
	public static WTDocument linkDocument(WTDocument document, File fff)
			throws Exception {
		if (document == null)
			return null;
		if (fff == null)
			return null;
		if (!fff.exists())
			return null;
		boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
		Transaction tx = null;
		try {
			if (!bTran) {
				tx = new Transaction();
				tx.start();
			}
			document = (WTDocument) PersistenceHelper.manager.refresh(document);
			ApplicationData app = ApplicationData.newApplicationData(document);
			app.setRole(ContentRoleType.PRIMARY);
			app.setFileName(fff.getName().toLowerCase());
			app.setUploadedFromPath("");
			// log.debug("--fff.getName()--"+fff.getName());
			FileInputStream is = new FileInputStream(fff);
			app = ContentServerHelper.service.updateContent(
					(ContentHolder) document, app, is);
			is.close();
			document = (WTDocument) ContentServerHelper.service
					.updateHolderFormat((FormatContentHolder) document);
			if (!bTran) {
				tx.commit();
				tx = null;
			}
		} catch (WTException e) {
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw new WTException(e);
		} finally {
			if (tx != null)
				tx.rollback();
		}
		return document;
	}

	/**
	 * 更新WTDocument的主内容（升级文档对象小版本）
	 * @param doc
	 * @param filePath
	 * @param fileName
	 * @return
	 */
	public static WTDocument updatePrimaryContent(WTDocument doc,File file){
		InputStream is=null;
		Transaction transaction = null;
		try {
			boolean bTran = PersistentObjectManager.getTransactionManager().isTransactionActive();
			if (!bTran) {
				transaction = new Transaction();
				transaction.start();
			}
	        doc=(WTDocument) GenericUtil.checkout(doc, "更新发布结果,保存到主内容中!");
			ContentHolder contentHolder=(ContentHolder)doc;
			if (contentHolder!=null) {
				contentHolder = ContentHelper.service.getContents(contentHolder);
				ContentItem contentTarget = ContentHelper.getPrimary((FormatContentHolder) contentHolder);
				ContentServerHelper.service.deleteContent(contentHolder, contentTarget);
			}
			linkDocument(doc, file);
			doc=(WTDocument) GenericUtil.checkin(doc, "更新发布结果,保存到主内容中!");
			if (!bTran) {
				transaction.commit();
				transaction = null;
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(transaction!=null){
				transaction.rollback();
			}
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		return doc;
	}

	public static WTDocument createWTDocument(String docNumber, String docName, String docType, WTContainer wtcon, Folder docFolder, String decription, Map ibas,String filePath) throws Exception, WTException {
		WTDocument doc = WTDocument.newWTDocument();
		doc.setName(docName);
//		if (docNumber == null || "".equals(docNumber)) {
//			doc.setNumber(WTDocUtil.getWTDocumentNumber());
//		} else {
//			doc.setNumber(docNumber);
//		}
		doc.setNumber(docNumber);

		TypeDefinitionReference typeDefinitionRef = null;
		if ((docType != null) && (docType.trim().length() != 0)) {
			typeDefinitionRef = TypedUtility.getTypeDefinitionReference(docType);
			if (typeDefinitionRef == null) {
				log.debug("ERROR :typeDefinitionRef is null,docType=" + docType);
				return null;
			} else {
				doc.setTypeDefinitionReference(typeDefinitionRef);
			}
		}
		EnumeratedType type[] = DocumentType.getDocumentTypeDefault().getSelectableValueSet();
		doc.setDocType((DocumentType) type[1]);
		EnumeratedType aenumeratedtype[] = DepartmentList.getDepartmentListSet();
		doc.setDepartment((DepartmentList) aenumeratedtype[1]);
		doc.setContainer(wtcon);
		doc.setOrganization(wtcon.getOrganization());
		if (docFolder != null) {
			FolderHelper.assignLocation(doc, docFolder);
		}
		if ((decription == null) || (decription.trim().length() == 0)){
			doc.setDescription(decription);
		}
//		if (ibas != null && !ibas.isEmpty()) {
//			LWCUtil.setValue(doc, ibas);
//		}
		doc = (WTDocument) PersistenceHelper.manager.store(doc);
		if (ibas != null && !ibas.isEmpty()) {
			LWCUtil.setValue(doc, ibas);
		}
		if (filePath != null) {
			File ff = new File(filePath);
			if (!ff.exists()) {
				log.debug("The doc file " + filePath + " not exists!");
				return doc;
			} else
				return linkDocument(doc, ff);
		}
		return doc;
	}

	public static WTDocument updateWTDocument(WTDocument doc, String name,
		String filename, HashMap iba, String checkinNotes)
		throws Exception {
		if (!doc.getName().equals(name)) {
			rename(doc, name);
		}
		doc = (WTDocument) GenericUtil.checkout(doc);
		if (iba != null && !iba.isEmpty()) {
			LWCUtil.setValue(doc, iba);
//			doc = (WTDocument) ibaUtil.store(doc);
		}
		doc = (WTDocument) PersistenceHelper.manager.save(doc);

		if (filename==null || filename.equals("")) {
			doc = (WTDocument) GenericUtil.checkin(doc,checkinNotes==null?"":checkinNotes);
			return doc;
		}
		//修改主文档
		ContentHolder contentholder = (ContentHolder) doc;
		contentholder = ContentHelper.service.getContents(contentholder);
		List contentListForTarget = ContentHelper.getContentListAll(contentholder);
		for (int i = 0; i < contentListForTarget.size(); i++) {
			ContentItem contentItem = (ContentItem) contentListForTarget
					.get(i);
			if (contentItem.getRole().toString().equals("PRIMARY")) {
				ContentServerHelper.service.deleteContent(contentholder,
						contentItem);
				break;
			}
		}
		ApplicationData appData = ApplicationData.newApplicationData(doc);
		appData.setRole(ContentRoleType.PRIMARY);
		appData.setFileName(doc.getNumber()+filename.substring(filename.lastIndexOf(".")));
		StandardContentService.setFormat(filename, appData);
		FileInputStream is = new FileInputStream(filename);
		appData = ContentServerHelper.service.updateContent(doc, appData,is);
		is.close();
		doc = (WTDocument) ContentServerHelper.service.updateHolderFormat(doc);

		doc = (WTDocument) GenericUtil.checkin(doc,checkinNotes==null?"":checkinNotes);
		return doc;
	}

//	public static List<EPMDescribeLink> getEPMDocumentByWTPart(WTPart wtpart) throws WTException {
//		List<EPMDescribeLink> epmSet = new ArrayList<EPMDescribeLink>();
//		QuerySpec qs = new QuerySpec(EPMDescribeLink.class);
//		SearchCondition condition = new SearchCondition(EPMDescribeLink.class,
//				"roleAObjectRef.key.id", "=", PersistenceHelper
//						.getObjectIdentifier(wtpart).getId());
//		qs.appendWhere(condition);
//		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
//		QueryResult qr = PersistenceHelper.manager.find(qs);
//		while (qr.hasMoreElements()) {
//			EPMDescribeLink link = (EPMDescribeLink) qr.nextElement();
//			epmSet.add(link);
//		}
//		return epmSet;
//	}

	public static Vector getAllEPMDocument(EPMDocument doc) throws Exception {
		Vector topics = new Vector(); // include topicgroup and topic
		QueryResult qr = PersistenceHelper.manager.navigate(doc, "uses", wt.epm.structure.EPMMemberLink.class);
		while (qr.hasMoreElements()) {
			EPMDocumentMaster d1 = (EPMDocumentMaster) qr.nextElement();
			EPMDocument d2 = getEPMDocument(d1.getNumber(), "");
			topics.addElement(d2);
		}
		return topics;
	}

	public static WTPart getWTPart(String num, String ver)
			throws Exception {
		WTPart part = null;
		QuerySpec qs = new QuerySpec(WTPart.class);
		SearchCondition sc = new SearchCondition(WTPart.class, WTPart.NUMBER,
				SearchCondition.EQUAL, num);
		qs.appendWhere(sc);
		if (StringUtil.hasContents(ver)) {
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(new KeywordExpression(
					"A0.versionida2versioninfo"), SearchCondition.EQUAL,
					new KeywordExpression("'" + ver + "'")));
		}
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression(
				"A0.latestiterationinfo"), SearchCondition.EQUAL,
				new KeywordExpression("1")));
			qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"), true));

		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements())
			part = (WTPart) qr.nextElement();
		return part;
	}

	



	public static Persistable getByConfigSpec(Mastered mastered,
			ConfigSpec configSpec) throws Exception {
		QueryResult qr = ConfigHelper.service.filteredIterationsOf(mastered,configSpec);
		Persistable result = null;
		if (qr.hasMoreElements()) {
			result = (Persistable) qr.nextElement();
		}
		while (qr.hasMoreElements()) {
			Persistable tmp = (Persistable) qr.nextElement();
			if (result.getPersistInfo().getObjectIdentifier().getId() < tmp
					.getPersistInfo().getObjectIdentifier().getId()) {
				result = tmp;
			}
		}
		return result;
	}

	public static List<Persistable[]> getUsesWTParts(WTPart wtpart,NavigationCriteria nc) throws Exception {
		List<Persistable[]> children = new ArrayList();
		QueryResult qr = WTPartHelper.service.getUsesWTParts(wtpart, nc);
		while (qr.hasMoreElements()) {
			Object ob = qr.nextElement();
			Persistable[] pers = (Persistable[]) ob;
			WTPart child = null;
			if (pers[1] instanceof WTPart) {
				child = (WTPart) pers[1];
				children.add(pers);
			}
		}
		return children;
	}

	

	//by wlj 查询WTPart的父级WTPart
	public static List<WTPartUsageLink> getParentWTPart(WTPart wtpart) throws WTException {
		List<WTPartUsageLink> set = new ArrayList<WTPartUsageLink>();
		QuerySpec qs = new QuerySpec(WTPartUsageLink.class);
		SearchCondition condition = new SearchCondition(WTPartUsageLink.class,
				"roleBObjectRef.key.id", "=", PersistenceHelper
						.getObjectIdentifier(wtpart.getMaster()).getId());
		qs.appendWhere(condition);
//			qs.appendOrderBy(WTPartUsageLink.class, "thePersistInfo.createStamp", true);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			WTPartUsageLink link = (WTPartUsageLink) qr.nextElement();
			set.add(link);
		}
		return set;
	}

	//获取根结点
	public static WTPart getRootWTPart(WTPart wtpart) throws Exception{
		List<WTPartUsageLink> set = GenericUtil.getParentWTPart(wtpart);
		if(set.size()>0){
			WTPartUsageLink ul = set.iterator().next();
			WTPart parent = (WTPart) ul.getRoleAObject();
			WTPart newVersonParent = GenericUtil.getWTPart(parent.getNumber(), "");
			String verson = VersionControlHelper.getIterationDisplayIdentifier(parent).toString();
			String newVerson = VersionControlHelper.getIterationDisplayIdentifier(newVersonParent).toString();
			if(!verson.equals(newVerson)){
				return wtpart;
			}
			WTPart rootWTPart = getRootWTPart(parent);
			return rootWTPart;
		}
		return wtpart;
	}

	//by wlj 查询EPMDocument的父级EPMDocument
	public static List<EPMMemberLink> getParentEPMDocument(EPMDocument child) throws WTException {
		List<EPMMemberLink> list = new ArrayList<EPMMemberLink>();
		QuerySpec qs = new QuerySpec(EPMMemberLink.class);
		SearchCondition condition = new SearchCondition(EPMMemberLink.class,
				"roleBObjectRef.key.id", "=", PersistenceHelper
						.getObjectIdentifier(child.getMaster()).getId());
		qs.appendWhere(condition);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			EPMMemberLink link = (EPMMemberLink) qr.nextElement();
			list.add(link);
		}
		return list;
	}

	//by wlj 查询EPMDocument的父级WTPart
	public static List<EPMDescribeLink> getParentWTPart(EPMDocument child) throws WTException {
		List<EPMDescribeLink> set = new ArrayList<EPMDescribeLink>();
		QuerySpec qs = new QuerySpec(EPMDescribeLink.class);
		SearchCondition condition = new SearchCondition(EPMDescribeLink.class,
				"roleBObjectRef.key.id", "=", PersistenceHelper
						.getObjectIdentifier(child).getId());
		qs.appendWhere(condition);
		qs.appendOrderBy(new OrderBy(new KeywordExpression("ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			EPMDescribeLink link = (EPMDescribeLink) qr.nextElement();
			set.add(link);
		}
		return set;
	}

	/**
	 * 根据 oid获取文档对应发布的pdf
	 * @param oid
	 * @return
	 * @throws Exception
	 */
	public static String getPDFURLByDocOid(String oid) throws Exception{
		Persistable p = (new ReferenceFactory()).getReference(oid).getObject();
		if (p instanceof WTPart) {
			WTPart wtpart = (WTPart) p;
			wt.viewmarkup.DerivedImage di = getRepresentation(wtpart);
			String url = getPDFURL(di);
			log.debug("====wtpart pdf url:"+url);
			return url;
		}else if(p instanceof EPMDocument) {
			EPMDocument epm = (EPMDocument) p;
			wt.viewmarkup.DerivedImage di = getRepresentation(epm);
			String url = getPDFURL(di);
			log.debug("====epm pdf url:"+url);
			return url;
		}
		return null;
	}

	public static wt.viewmarkup.DerivedImage getRepresentation(wt.representation.Representable representable) throws Exception {
		wt.representation.Representation representation = wt.representation.RepresentationHelper.service.getDefaultRepresentation(representable);
		if (representation == null) {
			return null;
		}
		wt.content.ContentHolder holder = wt.content.ContentHelper.service.getContents(representation);
		if (holder == null) {
			return null;
		}
		return (wt.viewmarkup.DerivedImage) holder;
	}

	public static String getPDFURL(wt.viewmarkup.DerivedImage di) throws Exception {
		return com.ptc.wvs.server.util.WVSContentHelper.getDownloadURLForType(di, wt.content.ContentRoleType.SECONDARY);
	}

	/**
     * 从网络Url中下载文件
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static void  downLoadFromUrl(String urlStr,String fileName,String savePath) throws IOException{
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        //设置超时间为10秒
        conn.setConnectTimeout(10*1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);

        //文件保存位置
        File saveDir = new File(savePath);
        if(!saveDir.exists()){
            saveDir.mkdir();
        }
        File file = new File(saveDir+File.separator+fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if(fos!=null){
            fos.close();
        }
        if(inputStream!=null){
            inputStream.close();
        }
        log.debug("info:"+url+" download success");
    }

    /**
     * 从输入流中获取字节数组
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static  byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    //number=Const.TextSIO_NO+GenericUtil.getObjectNumberBySeq("",Const.TextSIO_SQUEN,8);
    public static String getObjectNumberBySeq(String prefix, String SequenceName, int length) throws WTException {
		String num = PersistenceHelper.manager.getNextSequence(SequenceName);
		while (num.length() < length) {
			num = "0" + num;
		}
		if (prefix != null)
			num = prefix + num;
		return num;
	}

    public static EPMAuthoringAppVersion getEPMAuthoringAppVersion(
			String authoringApplication) throws Exception {
		QuerySpec qs = new QuerySpec(EPMAuthoringAppVersion.class);
		qs.appendWhere(new SearchCondition(EPMAuthoringAppVersion.class,
				EPMAuthoringAppVersion.AUTHORING_APPLICATION,
				SearchCondition.EQUAL, authoringApplication));
		QueryResult res = PersistenceHelper.manager.find(qs);
		qs.appendOrderBy(EPMAuthoringAppVersion.class,
				EPMAuthoringAppVersion.VERSION_NUMBER, true);
		if (res.hasMoreElements()) {
			return (EPMAuthoringAppVersion) res.nextElement();
		}
		return null;
	}

  //update by wlj
  	public static ContentHolder linkFile(ContentHolder ch, String filePath,String category)
  			throws Exception {
  		String filename = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
  		File file = new File(filePath);
  		FileInputStream is = new FileInputStream(file);
  		return linkFile(ch,filename,is,category);
  	}

  	//by wlj
  	public static ContentHolder linkFile(ContentHolder ch, String filename, String fileContent,String category) throws Exception{
  		return linkFile(ch,filename,new ByteArrayInputStream(fileContent.getBytes()),category);
  	}
  	//by wlj
  	public static ContentHolder linkFile(ContentHolder ch, String filename, InputStream is,String category)
  			throws Exception {
  		Transaction trans = null;
  		try {
  			trans = new Transaction();
  			trans.start();
  			ch = (ContentHolder) PersistenceHelper.manager.refresh(ch);
  			ApplicationData appData = ApplicationData.newApplicationData(ch);
  			appData.setRole(ContentRoleType.PRIMARY);
  			appData.setFileName(filename);
  			appData.setUploadedFromPath("");
  			appData.setCategory(category);
  			appData = ContentServerHelper.service.updateContent((ContentHolder) ch, appData, is);
  			is.close();
  			ch = (ContentHolder) ContentServerHelper.service
  					.updateHolderFormat((FormatContentHolder) ch);
  			trans.commit();
  		} catch (Exception e) {
  			if (trans != null)
  				trans.rollback();
  			throw e;
  		}
  		return ch;
  	}

  	public static ArrayList findByIBA(Class targetClass, String softtype,
			Map ibas, WTContainer con,String number,String name,boolean firstCreate) throws Exception {
		QuerySpec qs = new QuerySpec();
		qs.setAdvancedQueryEnabled(true);
		int targetIndex = qs.appendClassList(targetClass, true);
		boolean addAnd = false;
		if (softtype != null && !softtype.trim().equals("")){
			if (softtype.lastIndexOf("|") >= 0){
				softtype = softtype.substring(softtype.lastIndexOf("|") + 1);
			}
			int defIndex = qs.appendClassList(WTTypeDefinition.class, false);
			if (addAnd){
				qs.appendAnd();
			}
			qs.appendWhere(new SearchCondition(new KeywordExpression(
					"A0.IDA2TYPEDEFINITIONREFERENCE"), SearchCondition.EQUAL,
					new KeywordExpression("A1.ida2a2")));
			qs.appendAnd();
			qs.appendWhere(new SearchCondition(
					new KeywordExpression("A1.name"), SearchCondition.EQUAL,
					new KeywordExpression("'" + softtype + "'")));
			addAnd = true;
		}
		if(number != null && !number.trim().equals("")){
			SearchCondition sc = null;
			if(number.indexOf("*")>=0){
				number = number.replace("*", "%");
				sc = new SearchCondition(targetClass, "master>number",
						SearchCondition.LIKE, number);
			}else{
				sc = new SearchCondition(targetClass, "master>number",
						SearchCondition.EQUAL, number);
			}

			if (addAnd){
				qs.appendAnd();
			}
			qs.appendWhere(sc);
			addAnd = true;
		}
		if(name != null && !name.trim().equals("")){
			SearchCondition sc = null;
			if(name.indexOf("*")>=0){
				name = name.replace("*", "%");
				sc = new SearchCondition(targetClass, "master>name",
						SearchCondition.LIKE, name);
			}else{
				sc = new SearchCondition(targetClass, "master>name",
						SearchCondition.EQUAL, name);
			}

			if (addAnd){
				qs.appendAnd();
			}
			qs.appendWhere(sc);
			addAnd = true;
		}

		if (con != null) {
			if (addAnd){
				qs.appendAnd();
			}
			qs.appendWhere(new SearchCondition(new KeywordExpression(
					"A0.ida3containerreference"), SearchCondition.EQUAL,
					new KeywordExpression("'"
							+ con.getPersistInfo().getObjectIdentifier()
									.getId() + "'")));
			addAnd = true;
		}
		if (Versioned.class.isAssignableFrom(targetClass)) {
			if (addAnd){
				qs.appendAnd();
			}
			qs.appendWhere(new SearchCondition(new KeywordExpression(
					"A0.latestiterationinfo"), SearchCondition.EQUAL,
					new KeywordExpression("1")));
			qs.appendAnd();
			qs.appendOpenParen();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.statecheckoutInfo"), SearchCondition.EQUAL,new KeywordExpression("'wrk'")));//有检出状态时，取检出的WTPart

			qs.appendOr();
			qs.appendWhere(new SearchCondition(new KeywordExpression("A0.statecheckoutInfo"), SearchCondition.EQUAL,new KeywordExpression("'c/i'")));//没有检出状态时
			qs.appendCloseParen();

			addAnd = true;
		}

		String ibaName = null;
		String ibaValue = null;
		if (ibas != null) {
			Iterator iter = ibas.keySet().iterator();
			while (iter.hasNext()) {
				ibaName = (String) iter.next();
				ibaValue = (String) ibas.get(ibaName);
				QuerySpec subSelect = new QuerySpec();
				subSelect.setAdvancedQueryEnabled(true);
				subSelect.getFromClause().setAliasPrefix("B");
				int ibaNameIndex = subSelect.appendClassList(StringValue.class,
						false);
				int ibaValueIndex = subSelect.appendClassList(
						StringDefinition.class, false);
				subSelect.appendSelect(new ClassAttribute(StringValue.class,
						WTAttributeNameIfc.ID_NAME),
						new int[] { ibaNameIndex }, true);
				subSelect.appendWhere(new SearchCondition(
						new KeywordExpression("A0.ida2a2"),
						SearchCondition.EQUAL, new KeywordExpression(
								"B0.ida3a4")));
				subSelect.appendAnd();
				subSelect.appendWhere(new SearchCondition(
						new KeywordExpression("B0.ida3a6"),
						SearchCondition.EQUAL, new KeywordExpression(
								"B1.ida2a2")));
				subSelect.appendAnd();
				subSelect.appendWhere(new SearchCondition(
						new KeywordExpression("B1.name"),
						SearchCondition.EQUAL, new KeywordExpression("'"
								+ ibaName + "'")));
				subSelect.appendAnd();
				if (ibaValue == null){
					subSelect.appendWhere(new SearchCondition(
							new KeywordExpression("B0.value2"),
							SearchCondition.IS_NULL));
				}else{
					ibaValue = ibaValue.replace("*", "%");
					if(ibaValue.contains("%") ){
						subSelect.appendWhere(new SearchCondition(
								new KeywordExpression("B0.value2"),
								SearchCondition.LIKE, new KeywordExpression("'"
										+ ibaValue + "'")));
					}else{
						subSelect.appendWhere(new SearchCondition(
								new KeywordExpression("B0.value2"),
								SearchCondition.EQUAL, new KeywordExpression("'"
										+ ibaValue + "'")));
					}
				}
				if (addAnd){
					qs.appendAnd();
				}
				qs.appendWhere(new ExistsExpression(subSelect), null);
				addAnd = true;
			}
		}

//		if (addAnd){
//			qs.appendAnd();
//		}
//		qs.appendWhere(new SearchCondition(
//				new KeywordExpression("rownum"),
//				SearchCondition.LESS_THAN_OR_EQUAL, new KeywordExpression("100")));//只查100条


		if (firstCreate) {
			qs.appendOrderBy(new OrderBy(new KeywordExpression("A0B.ida2a2"),false));
			qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		}else{
			if (SubFolder.class.isAssignableFrom(targetClass)) {
				qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.name"),
						false));
			} else {
				qs.appendOrderBy(new OrderBy(new KeywordExpression(
						"A0.MODIFYSTAMPA2"), false));
			}
		}

    //log.debug("******findByIBA() SQL: "+qs);
		QueryResult qr = PersistenceHelper.manager.find(qs);
    //log.debug("******findByIBA() Finished!");
		ArrayList list = new ArrayList();
		while (qr.hasMoreElements()) {
			list.add(((Object[]) qr.nextElement())[0]);
		}
		return list;
	}

  	public static void removeChildren(EPMDocument pdoc) throws WTException {
		boolean enforce = wt.session.SessionServerHelper.manager.setAccessEnforced(false);
		try{
			QuerySpec qs = new QuerySpec(EPMMemberLink.class);
			SearchCondition condition = new SearchCondition(EPMMemberLink.class,
					"roleAObjectRef.key.id", "=", PersistenceHelper
							.getObjectIdentifier(pdoc).getId());
			qs.appendWhere(condition);
			QueryResult qr = PersistenceHelper.manager.find(qs);
			while (qr.hasMoreElements()) {
				EPMMemberLink link = (EPMMemberLink) qr.nextElement();
				PersistenceHelper.manager.delete(link);
			}
		}finally{
				SessionServerHelper.manager.setAccessEnforced(enforce);
		}
	}


  	public static String toUTF8(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					log.debug(ex);
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}
  	/**
  	 * 获取基线内容
  	 * @param baseline
  	 * @return
  	 * @throws WTException
  	 */
  	public static List getBaseLineContent(Baseline baseline) throws WTException{
  		List resultList = new ArrayList();
  		QueryResult qr = BaselineHelper.service.getBaselineItems(baseline);
  		while (qr.hasMoreElements()) {
			Object object = (Object) qr.nextElement();
			resultList.add(object);
		}
  		return resultList;
  	}
  	
  	public static List<ManagedBaseline> getBaselineWithLike(String num) throws WTException {
  		List list = new ArrayList();
		ManagedBaseline bl = null;
		QuerySpec qs = new QuerySpec(ManagedBaseline.class);
		SearchCondition sc = new SearchCondition(ManagedBaseline.class, ManagedBaseline.NUMBER, SearchCondition.LIKE, num+"%");
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			bl = (ManagedBaseline) qr.nextElement();
			list.add(bl);
		}
		return list;
	}
  	
  	/**
	 * 是否是组织管理员
	 * @return
	 * @throws WTException 
	 */
	public static boolean isOrgAdmin() {
		WTPrincipal currentUser;
		WTGroup group = GenericUtil.getGroup("ORG ADMIN");
		if(group==null){
			return false;
		}
		try {
			currentUser = SessionHelper.manager.getPrincipal();
			log.debug("============wlj currentUser:"+currentUser);
			log.debug("============wlj group:"+group);
			return group.isMember(currentUser);
		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 是否是站点管理员
	 * @return
	 * @throws WTException 
	 */
	public static boolean isAdministrators() {
		WTPrincipal currentUser;
		WTGroup group = GenericUtil.getGroup("Administrators");
		try {
			currentUser = SessionHelper.manager.getPrincipal();
			return group.isMember(currentUser);
		} catch (WTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	public static WTGroup getGroup(String groupName) {
		WTGroup gp = null;
		try {
			QuerySpec qs = new QuerySpec(WTGroup.class);
			SearchCondition sc = new SearchCondition(WTGroup.class, "name",
					SearchCondition.EQUAL, groupName);
			qs.appendSearchCondition(sc);
			log.debug(qs.toString());
			QueryResult qr = PersistenceHelper.manager.find(qs);
			log.debug("qr:"+qr.size());
			if (qr.hasMoreElements())
				gp = (WTGroup) qr.nextElement();
		} catch (WTException wte) {
			wte.printStackTrace();
		}
		return gp;
	}
	
	public static boolean isMember(String groupName, WTUser user) {
		boolean flag = false;
		try {
			WTGroup gp = getGroup(groupName);
			if (gp != null && gp.isMember(user))
				flag = true;
		} catch (WTException e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	/**
	 * 获取子件最大的行号
	 * @param wtpart
	 * @return
	 * @throws WTException
	 */
	public static long getMaxLine(WTPart wtpart) throws WTException{
		long maxLine = 0;
		long line = 0;
		QueryResult qr = WTPartHelper.service.getUsesWTPartMasters(wtpart);
		while (qr.hasMoreElements()) {
			WTPartUsageLink link = (WTPartUsageLink)qr.nextElement();
			line = link.getLineNumber().getValue();
			if (line > maxLine) {
				maxLine = line;
			}
		}
		return maxLine;
	}
	
	//得到类型下属性的所有枚举值
    public static Map getEnumerByIBAandSoftType(String softType,String attName){
		  Map listmap=new HashMap();
		  
		  TypeIdentifier ti=TypedUtility.getTypeIdentifier(softType);
		  try{
			  TypeDefinitionReadView view=TypeDefinitionServiceHelper.service.getTypeDefView(ti);
			  AttributeDefinitionReadView readView=view.getAttributeByName(attName);
			  if(readView==null){
				  return listmap;
			  }
			  Collection<ConstraintDefinitionReadView> collection=readView.getAllConstraints();
			  for(ConstraintDefinitionReadView con:collection){
				  String rule=con.getRule().getKey().toString();
				  if(rule.indexOf("com.ptc.core.lwc.server.LWCEnumerationBasedConstraint")>-1){
					  RuleDataObject rdo=con.getRuleDataObj();
					  if(rdo!=null){
						  Collection coll=rdo.getEnumDef().getAllEnumerationEntries().values();
						 Iterator<EnumerationEntryReadView>  it= coll.iterator();
						 while(it.hasNext()){
							 EnumerationEntryReadView ew=it.next();
							 Map<Locale,String> map =ew.getPropertyValueByName("displayName").getLocalizedValues();
							 listmap.put(ew.getName(),map);
						 }
					  }
				  }
			  }
		  }catch (Exception e) {
			// TODO: handle exception
			  e.printStackTrace();
		}
		  return listmap;
	  }
    
  	
  	/**
	 * 根据用户名获取系统用户
	 * 
	 * @param username
	 * @return
	 */
	public static WTUser getWTUserByName(String username) {
		WTUser user = null;
		try {
			QuerySpec qs = new QuerySpec(WTUser.class);
//			SearchCondition sc = new SearchCondition(WTUser.class, "name", SearchCondition.EQUAL, username);
			SearchCondition sc = new SearchCondition(new KeywordExpression("lower(A0.name)"), SearchCondition.EQUAL, new KeywordExpression("lower('" + username + "')"));
			qs.appendSearchCondition(sc);
			QueryResult qr = PersistenceHelper.manager.find(qs);
			if (qr.hasMoreElements())
				user = (WTUser) qr.nextElement();
		} catch (WTException wte) {
			wte.printStackTrace();
		}
		return user;
	}
	/**
	 * move a object to other foler
	 * 
	 * @param obj
	 * @param folder
	 * @return
	 * @throws Exception
	 */
	public static FolderEntry changeFolderAllVersion(WTObject obj, Folder folder) throws Exception {
		FolderEntry fe = null;
		boolean access = false;
		try {
			access = SessionServerHelper.manager.setAccessEnforced(false);
			if (obj instanceof WTDocument) {
				QueryResult qr = VersionTaskLogic.getAllVersions(((WTDocument) obj).getMaster());
				qr = (new LatestConfigSpec()).process(qr);
				while (qr.hasMoreElements()) {
					WTDocument wtdocument = (WTDocument) qr.nextElement();
					if (!FolderHelper.service.getFolder(wtdocument).equals(folder)) {
						wtdocument = (WTDocument) changeFolder(wtdocument, folder);
						PersistenceHelper.manager.refresh(wtdocument);
					}
				}
			} else if (obj instanceof EPMDocument) {
				QueryResult qr = VersionTaskLogic.getAllVersions(((EPMDocument) obj).getMaster());
				qr = (new LatestConfigSpec()).process(qr);
				while (qr.hasMoreElements()) {
					EPMDocument document = (EPMDocument) qr.nextElement();
					if (!FolderHelper.service.getFolder(document).equals(folder)) {
						document = (EPMDocument) changeFolder(document, folder);
						PersistenceHelper.manager.refresh(document);
					}
				}
			} else {
				if (FolderHelper.service.getFolder((FolderEntry) obj).equals(folder))
					return (FolderEntry) obj;
				fe = changeFolder((FolderEntry) obj, folder);
			}
		} finally {
			SessionServerHelper.manager.setAccessEnforced(access);
		}
		return (FolderEntry) PersistenceHelper.manager.refresh(obj);
	}
	
	public static void reassign(LifeCycleManaged lc) throws Exception{
		State state = lc.getState().getState();
		LifeCycleTemplateReference lifecycletemplatereference = lc.getLifeCycleTemplate();
        LifeCycleTemplate lifecycletemplate = (LifeCycleTemplate)lifecycletemplatereference.getObject();
        lifecycletemplate = (LifeCycleTemplate)VersionControlHelper.getLatestIteration(lifecycletemplate);
        lifecycletemplatereference = LifeCycleTemplateReference.newLifeCycleTemplateReference(lifecycletemplate);
        lc = LifeCycleHelper.service.reassign(lc, lifecycletemplatereference);
        lc = LifeCycleHelper.service.setLifeCycleState(lc, state);
        LifeCycleHelper.service.augmentRoles(lc);
        //LifeCycleHelper.service.augmentRoles((Team)lc.getTeamId().getObject());
	}
	
	/**
	 * 查询产品库
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public static PDMLinkProduct getPDMLinkProduct(String name)
			throws Exception {
		PDMLinkProduct product = null;
		QuerySpec qs = new QuerySpec(PDMLinkProduct.class);
		SearchCondition sc = new SearchCondition(PDMLinkProduct.class, PDMLinkProduct.NAME,
				SearchCondition.EQUAL, name);
		qs.appendWhere(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		if (qr.hasMoreElements())
			product = (PDMLinkProduct) qr.nextElement();
		return product;
	}
	/**
	 * 查询所有产品库
	 * @return
	 * @throws Exception
	 */
	public static List<PDMLinkProduct> getPDMLinkProduct() throws Exception {
		QuerySpec qs = new QuerySpec(PDMLinkProduct.class);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List list = new ArrayList();
		PDMLinkProduct product = null;
		while (qr.hasMoreElements()){
			product = (PDMLinkProduct) qr.nextElement();
			list.add(product);
		}
		return list;
	}
	
	public static List getEPMDocumentUsedBy(EPMDocument doc) throws Exception {
		List list = new ArrayList();
		QueryResult qr = EPMStructureHelper.service.navigateUsedBy(
				(EPMDocumentMaster) doc.getMaster(), null, true);
		while (qr.hasMoreElements()) {
			EPMDocument master = (EPMDocument) qr.nextElement();
			EPMDocument subDoc = GenericUtil.getEPMDocument(master.getNumber(), "");
			list.add(subDoc);
		}
		return list;
	}
	
	/**
	 * branchiditerationinfo: wtpart.getBranchIdentifier()
	 * type: 值类似:VR:wt.epm.EPMDocument
	 * @param workflowname
	 * @param branchiditerationinfo
	 * @param type
	 * @return
	 * @throws WTException
	 */
	public static List getOpenProcess(String workflowname, String branchiditerationinfo, String type) throws WTException {
		QuerySpec qs = new QuerySpec(WfProcess.class);
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.name"), SearchCondition.EQUAL,
				new KeywordExpression("'" + workflowname + "'")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.state"), SearchCondition.EQUAL,
				new KeywordExpression("'OPEN_RUNNING'")));

		qs.appendAnd();
//		qs.appendWhere(new SearchCondition(new KeywordExpression("a0.businessobjreference"), SearchCondition.EQUAL,
//				new KeywordExpression("'VR:wt.epm.EPMDocument:" + branchiditerationinfo + "'")));
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.businessobjreference"), SearchCondition.EQUAL,
				new KeywordExpression("'"+type+":" + branchiditerationinfo + "'")));
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List result = new ArrayList();
		while (qr.hasMoreElements()) {
			Object ob = qr.nextElement();
			result.add(ob);
		}
		return result;
	}
	
	/**
	 * branchiditerationinfo: wtpart.getBranchIdentifier()
	 * type: 值类似:VR:wt.epm.EPMDocument
	 * @param workflowname
	 * @param branchiditerationinfo
	 * @param type
	 * @return
	 * @throws WTException
	 */
	public static List getProcess(String workflowname, String branchiditerationinfo, String type) throws WTException {
		QuerySpec qs = new QuerySpec(WfProcess.class);
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.name"), SearchCondition.LIKE,
				new KeywordExpression("'" + workflowname + "%'")));
		qs.appendAnd();
//		qs.appendWhere(new SearchCondition(new KeywordExpression("a0.businessobjreference"), SearchCondition.EQUAL,
//				new KeywordExpression("'VR:wt.epm.EPMDocument:" + branchiditerationinfo + "'")));
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.businessobjreference"), SearchCondition.EQUAL,
				new KeywordExpression("'"+type+":" + branchiditerationinfo + "'")));
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"),true));
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List result = new ArrayList();
		while (qr.hasMoreElements()) {
			Object ob = qr.nextElement();
			result.add(ob);
		}
		return result;
	}
	
	/**
	 * 
	 * @param cs  WTPart, EPMDocument
	 * @param containerClassName 容器  如:PDMLinkProduct.class.getName()
	 * @param containerIda2a2 如:PDMLinkProduct的ida2a2
	 * @param softtypes 对象软属性
	 * @return
	 * @throws WTException 
	 */
	public static List getWTObject(Class cs, String containerClassName, long containerIda2a2, List<String> softtypes) throws WTException{
		QuerySpec qs = new QuerySpec();
		qs.addClassList(cs, true);
		qs.addClassList(WTTypeDefinition.class, false);
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.ida2typedefinitionreference"), SearchCondition.EQUAL, new KeywordExpression("a1.ida2a2")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.classnamekeycontainerreferen"), SearchCondition.EQUAL, new KeywordExpression("'"+containerClassName+"'")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.ida3containerreference"), SearchCondition.EQUAL, new KeywordExpression(containerIda2a2+"")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL, new KeywordExpression("1")));
		if (softtypes != null && !softtypes.isEmpty()) {
			String softtype = null;
			qs.appendAnd();
			qs.appendOpenParen();
			softtype = softtypes.get(0);
			if (softtype.lastIndexOf("|") >= 0){
				softtype = softtype.substring(softtype.lastIndexOf("|") + 1);
			}
			qs.appendWhere(new SearchCondition(new KeywordExpression("A1.name"), SearchCondition.EQUAL, new KeywordExpression("'"+softtype+"'")));
			for (int i=1;i<softtypes.size();i++) {
				softtype = softtypes.get(i);
				if (softtype.lastIndexOf("|") >= 0){
					softtype = softtype.substring(softtype.lastIndexOf("|") + 1);
				}
				qs.appendOr();
				qs.appendWhere(new SearchCondition(new KeywordExpression("A1.name"), SearchCondition.EQUAL, new KeywordExpression("'"+softtype+"'")));
			}
			qs.appendCloseParen();
		}
		qs.appendOrderBy(new OrderBy(new KeywordExpression("A0.ida2a2"), true));
		log.info(qs.toString());
		QueryResult qr = PersistenceHelper.manager.find(qs);
		List list = new ArrayList();
		while (qr.hasMoreElements()) {
			Object[] objs = (Object[]) qr.nextElement();
			list.add(objs[0]);
		}
		return list;
	}
	
	/**
	 * 获取文字内容载体
	 * @param epm
	 * @return
	 * @throws WTException
	 */
	public static WTPart getPartByEPMDoc(EPMDocument epm)throws WTException {
		QueryResult qrr = PersistenceHelper.manager.navigate(epm, EPMDescribeLink.DESCRIBES_ROLE, wt.epm.structure.EPMDescribeLink.class, true);//describes
        if (qrr.hasMoreElements()) {
            Object obj = qrr.nextElement();
            if (obj instanceof WTPart) {
            	WTPart part = (WTPart) obj;
                return part;
            }
        }
        return null;
    }
	
	/**
	 * get EPMDoc by UNIQUE_NDID
	 *
	 * @param uniqueId
	 * @return
	 * @throws Exception
	 */
	public static long getEPMMemberLinkId(String uniqueId) throws Exception {
		QuerySpec qs = new QuerySpec(EPMMemberLink.class);
		qs.appendWhere(new SearchCondition(EPMMemberLink.class, EPMMemberLink.UNIQUE_NDID, SearchCondition.EQUAL, uniqueId));
		QueryResult res = PersistenceHelper.manager.find(qs);
		if (res.hasMoreElements()) {
			EPMMemberLink link = (EPMMemberLink) res.nextElement();
			return link.getUniqueLinkID();
		}
		return Long.parseLong(PersistenceHelper.manager.getNextSequence("EPMLINK_SEQ"));
	}
	
	/**
	 * get EPMDoc by UNIQUE_NDID
	 *
	 * @param uniqueId
	 * @return
	 * @throws Exception
	 */
	public static long getEPMMemberLinkId(String uniqueId, long masterAida2a2) throws Exception {
		QuerySpec qs = new QuerySpec(EPMMemberLink.class);
		qs.addClassList(EPMDocument.class, false);
		qs.appendWhere(new SearchCondition(EPMMemberLink.class, EPMMemberLink.UNIQUE_NDID, SearchCondition.EQUAL, uniqueId));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A0.ida3a5"), SearchCondition.EQUAL, new KeywordExpression("A1.ida2a2")));
		qs.appendAnd();
		qs.appendWhere(new SearchCondition(new KeywordExpression("A1.ida3masterreference"), SearchCondition.EQUAL, new KeywordExpression(masterAida2a2+"")));
		
		QueryResult res = PersistenceHelper.manager.find(qs);
		if (res.hasMoreElements()) {
			EPMMemberLink link = (EPMMemberLink) res.nextElement();
			return link.getUniqueLinkID();
		}
		return Long.parseLong(PersistenceHelper.manager.getNextSequence("EPMLINK_SEQ"));
	}
	
	/**
	 * 
	 * @param doc1
	 * @param doc2
	 * @param refType RELATION
	 * @throws Exception
	 */
	public static void createEPMReferenceLink(EPMDocument doc1, EPMDocument doc2, String refType, int i)
			throws Exception {
		if (doc1 == null || doc2 == null)
			return;
		long masterAida2a2 = PersistenceHelper.getObjectIdentifier(doc1.getMaster()).getId();
		EPMReferenceLink link = EPMReferenceLink.newEPMReferenceLink(doc1, (EPMDocumentMaster) doc2.getMaster());
		link.setAsStoredChildName(doc2.getCADName());
		link.setDepType(8);
		link.setUniqueNDId("R/8/"+doc2.getCADName()+"/"+i);
		link.setUniqueLinkID(GenericUtil.getEPMMemberLinkId(link.getUniqueNDId(), masterAida2a2));// 2015wlj
		//RELATION INTERNAL
		link.setReferenceType(EPMReferenceType.toEPMReferenceType("RELATION"));
		PersistenceServerHelper.manager.insert(link);
	}
	/**
	 * 根据编号 版本 视图返回部件
	 * @param num
	 * @param ver
	 * @param viewName
	 * @return
	 * @throws Exception
	 */
	public static WTPart getPart(String num, String ver, String viewName)throws Exception {
    	if (viewName.equals(""))  viewName = "Design";
    	if ( num==null || num.equals("") ||  num.trim().equals("")) return null;
        View view = ViewHelper.service.getView(viewName);
        WTPart part = null;
        QuerySpec qs = new QuerySpec(WTPart.class);
        SearchCondition sc = new SearchCondition(WTPart.class, WTPart.NUMBER,SearchCondition.EQUAL, num);
        qs.appendWhere(sc);
        sc = new SearchCondition(WTPart.class, "view.key.id",SearchCondition.EQUAL, view.getPersistInfo().getObjectIdentifier().getId());
        qs.appendAnd();
        qs.appendWhere(sc);
        if (!ver.equals("")) {
            qs.appendAnd();
            qs.appendWhere(new SearchCondition(new KeywordExpression("A0.versionida2versioninfo"), SearchCondition.EQUAL,new KeywordExpression("'" + ver + "'")));
        }
        qs.appendAnd();
        qs.appendWhere(new SearchCondition(new KeywordExpression("A0.latestiterationinfo"), SearchCondition.EQUAL,new KeywordExpression("1")));
    
        qs.appendOrderBy(WTPart.class,"thePersistInfo.createStamp", true);
        QueryResult qr = PersistenceHelper.manager.find(qs);
       while (qr.hasMoreElements())
           { part = (WTPart) qr.nextElement();
              OneOffVersionInfo one=part.getOneOffVersionInfo();
              OneOffVersionIdentifier id=one.getIdentifier();
              String valueOneOff=id.getValue();
              if(valueOneOff==null)return part;                                    	 
          }
        return part;
    }
	/**
	 * 重置编号
	 * @param obj
	 * @param number
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 */
	public static void setPartNumber(WTObject obj, String number) throws WTException, WTPropertyVetoException {
		WTPart part = (WTPart) obj;
		Identified partidentified = (Identified) part.getMaster();
		WTPartMasterIdentity partmasteridentity = (WTPartMasterIdentity) partidentified.getIdentificationObject();
		partmasteridentity.setNumber(number);
		partidentified = IdentityHelper.service.changeIdentity(partidentified, partmasteridentity); // 更新名称
		PersistenceServerHelper.manager.update(partidentified);
		part = (WTPart) PersistenceHelper.manager.refresh(part);
	}
	/**
	 * 重置名称
	 * @param obj
	 * @param number
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 */
	public static void setWTDocName(WTObject obj, String name) throws WTException, WTPropertyVetoException {
		WTDocument doc = (WTDocument) obj;
		Identified docidentified = (Identified) doc.getMaster();
		WTDocumentMasterIdentity docmasteridentity = (WTDocumentMasterIdentity) docidentified.getIdentificationObject();
		docmasteridentity.setName(name);
		docidentified = IdentityHelper.service.changeIdentity(docidentified, docmasteridentity); // 更新名称
		PersistenceServerHelper.manager.update(docidentified);
		doc = (WTDocument) PersistenceHelper.manager.refresh(doc);
	}
	
}
